私は、外部依存関係のない純粋なPythonを2つのシーケンスの要素ごとに比較しようとしていました。私の最初の解決策だった:マップのパフォーマンスとstarmapのパフォーマンス?
list(map(operator.eq, seq1, seq2))
それから私は、私にはかなり似て見えたこれ、itertools
からstarmap
機能を発見しました。しかし、私のコンピュータで最悪の場合、それは37%速くなることが判明しました。それは私には明らかではなかったとして、私は発電機からの1つの要素を取得するために必要な時間を測定した(この方法が正しいかどうかわからない):取得要素で
from operator import eq
from itertools import starmap
seq1 = [1,2,3]*10000
seq2 = [1,2,3]*10000
seq2[-1] = 5
gen1 = map(eq, seq1, seq2))
gen2 = starmap(eq, zip(seq1, seq2))
%timeit -n1000 -r10 next(gen1)
%timeit -n1000 -r10 next(gen2)
271 ns ± 1.26 ns per loop (mean ± std. dev. of 10 runs, 1000 loops each)
208 ns ± 1.72 ns per loop (mean ± std. dev. of 10 runs, 1000 loops each)
第2の解決策は、24%よりパフォーマンスです。その後、彼らはlist
と同じ結果を出します。しかし、どこかから余分に13%増えます。
%timeit list(map(eq, seq1, seq2))
%timeit list(starmap(eq, zip(seq1, seq2)))
5.24 ms ± 29.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
3.34 ms ± 84.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
このようなネストされたコードのプロファイリングを深く理解する方法はわかりません。だから私の質問は、最初のジェネレータが検索速度が速く、list
で13%の余分なゲインを得る理由です。
EDIT: all
機能がlist
と交換したように、私の最初の意図は、代わりにall
の要素単位の比較を実行することでした。この置き換えはタイミング比に影響しません。私は気づくことができる
のWindows 10上ではCPython 3.6.2(64)
が理由だけではなく、使用しないで...と呼ばれる機能もCの関数であるとき
zip
とstarmap
が複数の引数を持つmap
を呼び出すよりも高速である点に至るまでの「偶然の一致」が多い 'SEQ1 = = seq2'? –@Błotosmętek訂正ありがとう!私の最初の意図は 'all'ではなく、要素的な比較でした。これは私の質問からは分かりませんでした:)本当に' all'の代わりに 'list'を置き換えると、時間の順序は同じになります。 – godaygo
Pythonのバージョンは?そして、これはCPythonですか? – MSeifert