7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Pythonで配列の中身をprintするときの実行速度比較

Last updated at Posted at 2019-03-02

#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()した方が速い!
7
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?