#Pythonで配列の中身をprintするときの実行速度比較
例えば、配列hoge
があったとして、その中身をすべて出力したいとする。そんな時いくつかコードの書き方が考えられると思うが、それぞれ実行速度はどれくらい違うのか計測した。
##テスト環境
OS | CPU | Pythonバージョン |
---|---|---|
Windows10 home 64bit | intel Core i5 7500 | 3.7.1 |
##計測方法
以下のようにtime.perf_counter()
を使って計測した。
time_start = time.perf_counter()
#時間計測したいコード
tim = time.perf_counter()- time_start
##1次元配列の場合
###出力フォーマット
hoge = [1, 2, 3, 4, 5]
だとしたら、
1
2
3
4
5
のように要素ごとに改行して出力するようなコードの書き方を比較する。
###テストした内容
今回測定したパターンは以下の3通り。hoge
は配列
#パターン1
length = len(hoge)
for i in range(length):
print(hoge(i))
#パターン2
for i in hoge:
print(i)
#パターン3
for i in hoge:
print("{}".format(i))
※追記
別パターンのアイデアをコメントでもらったので以下2つも試してみる。
#パターン4
print(*hoge, sep='\n')
#パターン5
print('\n'.join(map(str, hoge)))
ファイル出力で計測する場合はリダイレクトを使った。
###テスト結果
hogeをhoge = [i for i in range(L)]
として作成しそれぞれのパターンを3回テストして平均をとった。
####標準出力の場合(L = 1000)
パターン1:0.423026890966[sec]
パターン2:0.406021656333[sec]
パターン3:0.411023060333[sec]
パターン4:0.427671138[sec]
パターン5:0.007100579333[sec]
やはり長さが1000程度の配列ではそれほど差は出ないようである。
パターン5の print('\n'.join(map(str, hoge)))
が他の追随を許さないレベルで速い!!!
これほどまでに大きな差が出た原因としては、他のパターンがprint()関数をL回呼び出しているのに対し、パターン5は配列をjoin()で一つの文字列に結合してからprint()するので、print()関数の呼び出しが1回で済むというのが大きいのだろう。
####ファイル出力の場合(L = 1000000)
パターン1:1.2381535143333335[sec]
パターン2:1.1619043353333334[sec]
パターン3:1.4380140773333334[sec]
パターン4:1.0475442879999[sec]
パターン5:0.27567296[sec]
パターン1は2回参照しているが意外にもまあまあの速度である。
一番早いのは一番単純な書き方であるパターン2となった。
やはりパターン5の print('\n'.join(map(str, hoge)))
が速い!!!
formatを使ったパターン3は一番遅い結果となった。
##2次元配列の場合は?
このままではformatが不憫な結果で終わってしまいそうなので2次元配列の場合についても検証した。
hoge を N×L の配列とする。
###出力フォーマット
hoge = [[1, 2], [3, 4], [5, 6]]
だとしたら、
1 2
3 4
5 6
のような出力をするコードの書き方について比較する。
###テストした内容
今回はパターン1は割愛.
N=2の場合の例。
#パターン2
for i in hoge:
print(i[0], i[1])
#パターン3
for i in hoge:
print("{} {}".format(i[0], i[1]))
※追記
1次元配列のテスト結果からprint()関数を呼ぶ回数が問題であると予想して、以下のようにprint()を1度しか呼ばないパターンを作ってみた。これをパターン4とする。
#パターン4
fuga = [" ".join(map(str, i)) for i in hoge]
print('\n'.join(map(str, fuga)))
###テスト結果
####ファイル出力(N = 2, L = 1000000)
パターン2:2.13243174633[sec]
パターン3:1.600395958[sec]
お、結構差が出る結果になった。N=2でだいたい0.5秒ぐらいの差である。これはNが大きくなるほど差が広がるのでは?と思ってN=5の場合についても調査した。
####ファイル出力(N = 5, L = 1000000)
パターン2:4.422985526[sec]
パターン3:2.030369288[sec]
予想はあたりのようで、N=5の場合はなんと倍以上の差が出た。
####パターン4の結果(ファイル出力、N = 5, L = 1000000)
パターン4:1.5420818646666667[sec]
formatを使った場合よりもさらに0.5秒ほど速い!!!
しかし思ったよりは速くなってはいない印象である。print()を1000000回呼ぶのと、join()を5000000回呼ぶのにかかる時間の差がだいたいこれぐらいってことか?
##まとめ
-
1次元配列をprintする場合は、for i in hoge: print(i)
が速いが、他と比べてそこまで差はない。- join()で結合してから一気にprint()するのが圧倒的に早いです。
-
2次元配列の場合は、1次元目の長さが分かっているならformatを使ってprintするのが速い。- 2次元の場合でも、なるべくjoin()で結合してからprint()した方が速い!