2008年2月28日木曜日

【Python】for文よりリスト内包記法のほうが効率的?


中で関数を呼ぶときは、for文を使うよりリスト内包記法を使う方が処理が速い。たとえば、以下の2つのスクリプトを試してみる。

■1.py
def a():
return "a"
s = ""
for _ in range( 0, 30000000 ):
s += a()
■2.py
def a():
return "a"
s = "".join( a() for _ in range( 0, 30000000 ) )

結果は以下。

■1.py
$ time python 1.py
real 1m45.563s
user 0m19.425s
sys 0m0.974s
■2.py
$ time python 2.py
real 1m4.801s
user 0m11.880s
sys 0m1.139s
後者の方が約60%の時間で処理できている。


ちなみに、以下のように関数呼び出しをなくしてみると・・・

■1.py
s = ""
for _ in range( 0, 30000000 ):
s += "a"
■2.py
s = "".join( "a" for _ in range( 0, 30000000 ) )

結果はこれ。

■1.py
$ time python 1.py
real 0m14.904s
user 0m13.254s
sys 0m0.972s
■2.py
$ time python 2.py
real 0m35.092s
user 0m6.368s
sys 0m1.125s
逆に、後者の方が遅いという結果に。

「文字列の連結は遅くて.joinメソッドは速い」という問題では
ないみたい。ちゃんと調べるか・・・?

2 件のコメント:

匿名 さんのコメント...

http://d.hatena.ne.jp/yumimue/20071226/1198670253

関数呼び出しをなくした 1.py の場合にはインプレイス処理がされているのかもしれませんね。

kamonama さんのコメント...

インプレイス処理というのは、「代入時に新たなオブジェクトを生成して代入するのではなく、以前のオブジェクトの内容を変更する」ということでしょうか?上の例だと、sの内容が破壊的にどんどん変更されていく?

けど、「s += "a"」と「s += a()」とでそこの処理は変わるのかな?CPythonではどうなってるんでしょう?

むぅ・・・