rubyとpythonにおけるfor文と関数型メソッドの速度比較
Contents
目的
for文と関数型メソッド(map)のどちらが効率的かの参考のため
測定パターン
| パターン | 説明 | 
|---|---|
| パターン1 | 1万個(0〜9999)の要素を持つ配列の2乗を計算した配列を作成する。 | 
| パターン2 | 1万個(0〜9999)の要素を持つ配列から3または5の倍数抽出した配列を作成する。 | 
| パターン3 | 1万個(0〜9999)の要素を持つ配列の総和を計算する。 | 
| パターン4 | 9999個の文字列”hoge”と最後尾に文字列”fuga”を持つ配列から文字列”fuga”の有無を調べる。 | 
| パターン5 | 0〜9999をキーにしてキーの2乗を値とするハッシュを作成する。 | 
測定パターン(バリエーション解説)
ruby
| パターン | メソッド名 | 説明 | 
|---|---|---|
| パターン1-1 | make_power_list_basic | for文で作成した | 
| パターン1-2 | make_power_list_map | map関数を使用した | 
| パターン2-1 | make_filter_list_basic | for文で作成した | 
| パターン2-2 | make_filter_list_map | map関数を使用した | 
| パターン3-1 | make_sum_list_basic | for文で作成した | 
| パターン3-2 | make_sum_list_inject | inject関数を使用した | 
| パターン3-3 | make_sum_list_inject | inject関数で使用する関数をシンボル呼び出しにして効率化した | 
| パターン4-1 | make_search_list_basic | for文で作成した | 
| パターン4-2 | make_search_list_include | include関数を使用した | 
| パターン5-1 | make_power_hash_basic | for文で作成した | 
| パターン5-2 | make_power_hash_zip_map | 値の配列をmap関数で作成し、zip関数でhashの元配列を作成した | 
python
| パターン | メソッド名 | 説明 | 
|---|---|---|
| パターン1-1 | make_power_list_basic | for文で作成した | 
| パターン1-2 | make_power_list_map | map関数を使用した | 
| パターン1-3 | make_power_list_compreh | リスト内包表記を使用した | 
| パターン2-1 | make_filter_list_basic | for文で作成した | 
| パターン2-2 | make_filter_list_filter | filter関数を使用した | 
| パターン2-3 | make_filter_list_compreh | リスト内包表記を使用した | 
| パターン3-1 | make_sum_list_basic | for文で作成した | 
| パターン3-2 | make_sum_list_reduce | reduce関数を使用した | 
| パターン3-3 | make_sum_list_sum | sum関数を使用した | 
| パターン4-1 | make_search_list_basic | for文で作成した | 
| パターン4-2 | make_search_list_index | index関数を使用して戻り値があれば1を返すようにした | 
| パターン4-3 | make_search_list_compreh | リスト内包表記を使用した | 
| パターン5-1 | make_power_hash_basic | for文で作成した | 
| パターン5-2 | make_power_hash_zip_map | 値リストをmap関数で作成し、dictの元をzip関数で作成した | 
| パターン5-3 | make_power_hash_zip_compreh | 値リストをリスト内包表記で作成し、dictの元をzip関数で作成した | 
| パターン5-4 | make_power_hash_compreh | リスト内包表記でキーと値のタプルを作成する方式を使用した | 
測定方法
各パターンを10000回繰り返した時間を測定する。
環境
CPU
Intel(R) Core(TM) i7-2677M CPU @ 1.80GHz
python
$ python -V
Python 2.7.3
ruby
$ ruby -v
ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-linux]
結果
ruby
$ ruby loop.rb
***make_power_list_basic***
      user     system      total        real
 22.540000   0.010000  22.550000 ( 22.580915)
***make_power_list_map***
      user     system      total        real
 14.370000   0.010000  14.380000 ( 14.394143)
***make_filter_list_basic***
      user     system      total        real
 26.740000   0.000000  26.740000 ( 26.767431)
***make_filter_list_map***
      user     system      total        real
 26.120000   0.020000  26.140000 ( 26.161219)
***make_sum_list_basic***
      user     system      total        real
 11.560000   0.000000  11.560000 ( 11.568072)
***make_sum_list_inject***
      user     system      total        real
 13.880000   0.000000  13.880000 ( 13.891798)
***make_sum_list_inject_symbol***
      user     system      total        real
 11.550000   0.000000  11.550000 ( 11.566363)
***make_search_list_basic***
      user     system      total        real
 10.100000   0.250000  10.350000 ( 10.365433)
***make_search_list_include***
      user     system      total        real
  6.390000   0.000000   6.390000 (  6.394231)
***make_power_hash_basic***
      user     system      total        real
 39.340000   0.130000  39.470000 ( 39.507706)
***make_power_hash_zip_map***
      user     system      total        real
 26.540000   0.000000  26.540000 ( 26.579716)
python
$ python loop.py
##                                 user       sys     total      real
make_power_list_basic           13.0800    0.0100   13.0900   13.1003
make_power_list_map             12.4900    0.0000   12.4900   12.5002
make_power_list_compreh          6.1500    0.0000    6.1500    6.1630
make_filter_list_basic          21.7700    0.0000   21.7700   21.7847
make_filter_list_filter         21.6400    0.0000   21.6400   21.6599
make_filter_list_compreh        16.9500    0.0000   16.9500   16.9694
make_sum_list_basic              5.6800    0.0000    5.6800    5.6786
make_sum_list_reduce            10.0700    0.0000   10.0700   10.0751
make_sum_list_sum                1.5800    0.0000    1.5800    1.5816
make_search_list_basic           4.7800    0.0000    4.7800    4.7857
make_search_list_index           1.7400    0.0000    1.7400    1.7430
make_search_list_compreh         3.6300    0.0000    3.6300    3.6309
make_power_hash_basic           13.3500    0.0000   13.3500   13.3585
make_power_hash_zip_map         31.1400    0.0000   31.1400   31.1695
make_power_hash_zip_compreh     24.5300    0.0000   24.5300   24.5598
make_power_hash_compreh         22.0500    0.0000   22.0500   22.0788
パターン別結果
| pattern | lang | method | user | sys | total | real | 
|---|---|---|---|---|---|---|
| pattern1 | ruby | make_power_list_basic | 22.5400 | 0.0100 | 22.5500 | 22.5809 | 
| pattern1 | ruby | make_power_list_map | 14.3700 | 0.0100 | 14.3800 | 14.3941 | 
| pattern1 | python | make_power_list_basic | 13.0800 | 0.0100 | 13.0900 | 13.1003 | 
| pattern1 | python | make_power_list_map | 12.4900 | 0.0000 | 12.4900 | 12.5002 | 
| pattern1 | python | make_power_list_compreh | 6.1500 | 0.0000 | 6.1500 | 6.1630 | 
| pattern2 | ruby | make_filter_list_basic | 26.7400 | 0.0000 | 26.7400 | 26.7674 | 
| pattern2 | ruby | make_filter_list_map | 26.1200 | 0.0200 | 26.1400 | 26.1612 | 
| pattern2 | python | make_filter_list_basic | 21.7700 | 0.0000 | 21.7700 | 21.7847 | 
| pattern2 | python | make_filter_list_filter | 21.6400 | 0.0000 | 21.6400 | 21.6599 | 
| pattern2 | python | make_filter_list_compreh | 16.9500 | 0.0000 | 16.9500 | 16.9694 | 
| pattern3 | ruby | make_sum_list_basic | 11.5600 | 0.0000 | 11.5600 | 11.5680 | 
| pattern3 | ruby | make_sum_list_inject | 13.8800 | 0.0000 | 13.8800 | 13.8917 | 
| pattern3 | ruby | make_sum_list_inject_symbol | 11.5500 | 0.0000 | 11.5500 | 11.5663 | 
| pattern3 | python | make_sum_list_basic | 5.6800 | 0.0000 | 5.6800 | 5.6786 | 
| pattern3 | python | make_sum_list_reduce | 10.0700 | 0.0000 | 10.0700 | 10.0751 | 
| pattern3 | python | make_sum_list_sum | 1.5800 | 0.0000 | 1.5800 | 1.5816 | 
| pattern4 | ruby | make_search_list_basic | 10.1000 | 0.2500 | 10.3500 | 10.3654 | 
| pattern4 | ruby | make_search_list_include | 6.3900 | 0.0000 | 6.3900 | 6.3942 | 
| pattern4 | python | make_search_list_basic | 4.7800 | 0.0000 | 4.7800 | 4.7857 | 
| pattern4 | python | make_search_list_index | 1.7400 | 0.0000 | 1.7400 | 1.7430 | 
| pattern4 | python | make_search_list_compreh | 3.6300 | 0.0000 | 3.6300 | 3.6309 | 
| pattern5 | ruby | make_power_hash_basic | 39.3400 | 0.1300 | 39.4700 | 39.5077 | 
| pattern5 | ruby | make_power_hash_zip_map | 26.5400 | 0.0000 | 26.5400 | 26.5797 | 
| pattern5 | python | make_power_hash_basic | 13.3500 | 0.0000 | 13.3500 | 13.3585 | 
| pattern5 | python | make_power_hash_zip_map | 31.1400 | 0.0000 | 31.1400 | 31.1695 | 
| pattern5 | python | make_power_hash_zip_compreh | 24.5300 | 0.0000 | 24.5300 | 24.5598 | 
| pattern5 | python | make_power_hash_compreh | 22.0500 | 0.0000 | 22.0500 | 22.0788 | 
所感
- rubyでは関数型メソッドを使用することで時間を短縮できる場合が多い。
- ただし、injectでは性能が遅くなってしまい、シンボル呼び出しで高速化してやっとfor文並となる結果だった。
- pythonでは関数型メソッドを使用することの速度上のメリットはなかった。
- 特にreduceでは倍近く遅くなった。
- リスト内包表記を使うと早い。
- sum早い。
web2pyでwiki化する方法
はじめに
プラグインを使わなくてもできるのでメモ
手順
- コントローラー(default.pyなど)に以下を追記する。
# This goes in the controller which will present # the wiki interface (usually default.py) def wiki(): return auth.wiki()
- <コントローラー>/wiki.html(例:default/wiki.html)に以下を追記する。
{{extend 'layout.html'}} <!-- Note that the response item named content contains the helper returned by the auth.wiki() call and you can choose where to place it within your view layout --> {{=content}}
- 以下のURLにアクセスする。
http://<web2pyアプリのURL>/<コントローラー>/wiki
参考
- Wikifying web2py apps
- http://www.web2pyslices.com/slice/show/1565/wikifying-web2py-apps