5月 2015 | 忘れたらググればいい

2015年5月9日土曜日

Pythonで一定長のリスト初期化にかかる時間の比較

元ネタ

あなたのPythonを爆速にする7つの方法

あと時間計測ならば1回だけじゃなくて,何回か実行した平均を取った方がいい.

条件を揃えてやってみた

全要素が0のリストの生成

  • 空の配列に1つずつ0をappend (list_0_append)
  • リスト内包表記 (list_0_comp)
  • 乗算 (list_0_multi)
  • array (list_0_array)
  • rangeで作ったリストに0を代入 (list_0_range)

要素が[0, 1, ..., n-1]のリストの生成

  • 空の配列に1つずつ数値をappend (list_i_append)
  • リスト内包表記 (list_i_comp)
  • 全0のリストを作ったあとに代入 (list_i_multi)
  • array (list_i_array)
  • range (list_i_range)

実証スクリプト

結果

% python bench.py -n 1000000
--Python version--
2.7.9 (v2.7.9:648dcafa7e5f, Dec 10 2014, 10:10:46) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]

--list_0--
list_0_append(1000000) in 0.229992(s)
list_0_comp(1000000) in 0.087843(s)
list_0_multi(1000000) in 0.016838(s)
list_0_array(1000000) in 0.212526(s)
list_0_range(1000000) in 0.175999(s)

--list_i--
list_i_append(1000000) in 0.241931(s)
list_i_comp(1000000) in 0.112636(s)
list_i_multi(1000000) in 0.155012(s)
list_i_array(1000000) in 0.237255(s)
list_i_range(1000000) in 0.050963(s)

全要素0であっても乗算が一番速かった. [0, 1,...,n-1]の場合は,乗算よりリスト内包表記の方が速い.が,range(n)の方がもっと速かった.

pypyでもやってみた

pypy bench.py -n 1000000
--Python version--
2.7.9 (9c4588d731b7, Mar 23 2015, 16:20:40)
[PyPy 2.5.1 with GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]

--list_0--
list_0_append(1000000) in 0.152410(s)
list_0_comp(1000000) in 0.014103(s)
list_0_multi(1000000) in 0.010896(s)
list_0_array(1000000) in 0.022531(s)
list_0_range(1000000) in 0.022315(s)

--list_i--
list_i_append(1000000) in 0.143897(s)
list_i_comp(1000000) in 0.014448(s)
list_i_multi(1000000) in 0.016995(s)
list_i_array(1000000) in 0.023090(s)
list_i_range(1000000) in 0.000005(s)

CPythonよりだいぶ速い.list_i_rangeは異常 (笑).

結論

全要素同じの場合は乗算,[0, 1,...,n-1]ならばrangeが速い. そしてpypy超速い (もちろんメモリやCPUの使い方まで比較してないので一概にpypyがいいとは言えない).