6

少し不自然な実験で、Python の組み込み関数のいくつかを numpy の関数と比較したいと思いました。しかし、これらのタイミングを取り始めたとき、私は何か奇妙なことに気づきました.

私が次のように書いたとき:

import timeit
timeit.timeit('import math; math.e**2', number=1000000)

非常に統計的に有意な方法で、ほぼランダムに交互に 2 つの異なる結果が得られます。

2 秒と 0.5 秒を交互に繰り返します。

これは私を混乱させたので、何が起こっているのかを理解するためにいくつかの実験を行ったが、私はさらに混乱した. そこで、次の実験を試みました。

[timeit.timeit('import math; math.e**2', number=1000000) for i in xrange(100)]

これは完全に 0.5 の数値につながりました。次に、これをジェネレーターでシードしようとしました:

test = (timeit.timeit('import math; math.e**2', number=1000000) for i in xrange(100))
[item for item in test]

これにより、完全に 2.0 番号でいっぱいのリストが作成されました。

alecxe の提案で、timeit ステートメントを次のように変更しました。

timeit.timeit('math.e**2', 'import math', number=1000000)

これは同様に約 0.1 秒と 0.4 秒を交互に繰り返しましたが、ジェネレーターとリスト内包表記を比較する実験を再実行したところ、今回は結果が反転しました。つまり、ジェネレーター式は定期的に 0.1 秒の数値を考え出しましたが、リスト内包表記は 0.4 秒の数値の完全なリストを返しました。

直接コンソール出力:

>>> test = (timeit.timeit('math.e**2', 'import math', number=1000000) for i in xrange(100))
>>> test.next()
0.15114784240722656

>>> timeit.timeit('math.e**2', 'import math', number=1000000)
0.44176197052001953
>>> 

編集:dwmを実行しているUbuntu 12.04を使用しています.xtermとgnome-terminalの両方でこれらの結果を見てきました。私はpython 2.7.3を使用しています

ここで何が起こっているか知っている人はいますか?これは私には本当に奇妙に思えます。

4

1 に答える 1

1

ここでいくつかのことが起こっていることが判明しましたが、明らかにこれらの癖のいくつかは私のマシンに固有のものである可能性がありますが、誰かが同じことに困惑した場合に備えて投稿する価値があると思います.

まず、2 つの timeit 関数には次の点で違いがあります。

timeit.timeit('math.e**2', 'import math', number=1000000)

import ステートメントは遅延ロードされます。これは、次の実験を試すと明らかになります。

timeit.timeit('1+1', 'import math', number=1000000)

対:

timeit.timeit('1+1', number=1000000)

したがって、リスト内包表記で直接実行すると、この import ステートメントがすべてのエントリに対してロードされているように見えます。(これの正確な理由は、おそらく私の構成に関連しています)。

それを過ぎて、元の質問に戻ると、実際には 3/4 の時間がインポート計算に費やされたように見えるので、方程式が生成されたとき、反復間のキャッシュ ストレージはなく、インポート キャッシュがあったと推測しています。リスト内包表記内 (繰り返しますが、これの正確な理由はおそらく構成固有です)

于 2013-09-01T19:42:39.340 に答える