過去の日記

2020-05-21 [長年日記]

"forループが遅い"は正しくない [Python]

"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]

がさらに速いので"内包表記と(関数呼び出しを伴わない)式で書けるならそれでいい"ということで。