元ネタ
1はできるlistが違うから比較として不適切では? そしてpypyを使うのがいろいろ解決してしまうこともある | あなたのPythonを爆速にする7つの方法 http://t.co/0lWErBIzU4
— Yuichiro Fukubayashi (@fukubaya) 2015, 5月 8
あと時間計測ならば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がいいとは言えない).