ぼくのかんがえたさいきょうの

archiving something about I'm interested in; computer etc.

rubyとpythonにおけるfor文と関数型メソッドの速度比較

目的

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]

Benchmarker

ruby:benchmark

python:Benchmarker ( pip install benchmarker でインストール)

結果

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化する方法

はじめに

プラグインを使わなくてもできるのでメモ

手順

  1. コントローラー(default.pyなど)に以下を追記する。
# This goes in the controller which will present
# the wiki interface (usually default.py)
def wiki():
    return auth.wiki()
  1. <コントローラー>/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}}
  1. 以下のURLにアクセスする。
http://<web2pyアプリのURL>/<コントローラー>/wiki