2020-05-21 [長年日記]
■"forループが遅い"は正しくない
"forループが遅いからmapで書こう"は正しくない。
forループより「Pythonで書かれた関数(lambda含む)」の呼び出しコストの方が馬鹿にならない。
リストに入った文字列に対して、それぞれ2文字目から2文字分を切り取った文字列でリストを作ることを考える(まだ曖昧だけど本筋じゃないので許して)
seq = [''.join(str(random.randint(0, 9)) for s in range(5)) for _ in range(1_000_000)]
とかして用意しておこう。
result = list(map(lambda x: x[2:4], seq))
より、愚直なforループ
result = [] for x in seq: result.append(x[2:4])
の方が速い。
しかし"mapが遅い"という結論にははならない。
愚直なforループより、
result = list(map(itemgetter(slice(2, 4)), seq))
の方が速いから。(itemgetter は operatorモジュールからimportすること)
lambdaとitemgetterとの差から、"mapが遅い"のではなくて、"lamdaの呼び出し/実行が遅い"と考えるのがいいだろう。
とはいえ結局、
result = [x[2:4] for x in seq]
がさらに速いので"内包表記と(関数呼び出しを伴わない)式で書けるならそれでいい"ということで。