Pythonにおける配列生成の速度比較
序論|配列生成における生成速度
n 個の x からなるベクトル,あるいは,連続する整数 x | 0, 1 .... , n に対して、f(x) の値から配列を生成したいというケースが多々発生する. このとき,内包表記,map関数,などどういう手法をとればよいのかを検討してみる.
1. n 個の定数から成る配列
方法
例えば,n個の 1 から成る配列を生成することを考える.
下記の4つの手法で配列を生成する計算時間を比較する.ただし,Numpy の出力結果は1行10000000列の行列である.
# 内包表記 a = [1 for _ in xrange(10000000)] # append b = [] for _ in xrange(10000000): b.append(1) # map関数 c = map(lambda _: 1, xrange(10000000)) # Numpy np.ones((1, 10000000))
30回の試行を行った結果を下記に示す.
結果
# 内包表記 0.8121745±0.03523441 # append 1.984215±0.05489317 [s] # map関数 1.457514±0.0431716 [s] # Numpy 0.03261587±0.003949044 [s]
結論
予想通りCで実行されているNumpy が最も早い. 他の3種類の中では,内包表記が早いことが示された.mapは関数呼び出しに要する遅延であると考えられる.appendは配列の生成ではなく,要素の追加であるため,前述の2種とは異なり速度も遅い.
2. 関数の値を要素とする配列
方法
下記の関数の値からなる配列を生成する.
def double(x): return x*x
# 内包表記 a = [double(x) for x in xrange(10000000)] # append b = [] for x in xrange(10000000): b.append(double(x)) # map関数 c = map(double, xrange(10000000))
同様に,30回の試行を行った結果を下記に示す.
結果
# 内包表記 3.416236±0.2539137 [s] # append 4.974325±0.4619621 [s] # map関数 2.10843±0.1802408 [s]
結論
map関数が最も早いことが示された.関数の値を要素とする場合,各手法において同様に遅延が発生する.この場合においては,map関数が最も高速配列を生成できることが示唆される.
総論
- Numpy は早い
- 関数呼び出し無し => 内包表記
- 関数呼び出し有り => Map関数