なかなか難しい
もともとライブラリすらないようなピュアな組み込み系からITに転職したこともあり、どうしても高級言語に感覚がついていってないことがある。というより、ついつい楽にコードがかけることから、あまり深く考えずに書いて失敗することがある。そんな一例を自分への戒めを含めて書いてみたいと思う。
こんなコードを書いてみた。
実際には違うコードだが、簡略化すると以下のような感じ。※実際は追加する文字がループごとに変わります。
a = "hogehoge\r\n"
count = 10000000
for i in range(0, count):
a += "hogehoge\r\n"
Pythonに詳しいおっちゃんに、「こりゃいかんよ」、と教えていただいた。
さて何がいけないのか。まずは、実際に時間を計ってみる。
import time
a = "hogehoge\r\n"
count = 10000000
start = time.time()
for i in range(0, count):
a += "hogehoge\r\n"
elapsed_time = time.time() - start
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
自分の環境では、2.499990940093994秒かかった。以下のように書き換えてみる。
a = ["hogehoge"]
count = 10000000
start = time.time()
for i in range(0, count):
a.append("hogehoge")
b = '\r\n'.join(a)
elapsed_time = time.time() - start
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
0.9330928325653076秒になった。ぜんぜんちゃうやん。なんだこれ。
str型はimmutable、list型はmutable
str型に対して+=をすると、新規にメモリを確保してコピーするので時間がかかるようだ。listはmutableなので、新しいメモリ領域だけを追加する。そりゃ速度に違いが出るよね。
もう少し調べてみる
ループ数が少ないと、+=の方が早いようだ。自分の環境では100ループくらいまでおおむね+=の方が早かった。しかし、200ループ超えたあたりからlistを使った方が早くなった。なんで??
反省点
Pythonは楽にプログラミングできるし、初心者でもとっつきやすい。しかし、一つ一つ理解していないと結構痛い目にあうようだ。まだまだ勉強が必要です。
他にもよいアイデアがある方、どしどしコメント下さい!!お待ちしております!