インターラブルで実行filter
していて、結果をシーケンスに格納したい(シーケンスを使用できるようにするためにシーケンスが必要ですrandom.choice
)。フィルタオブジェクトからセットを作成する方が、リストやタプルを作成するよりもはるかに高速であることに気付きました。何故ですか?最初に、フィルタータイプはセットのサブタイプであり、これを説明しますが、関数は実際にはジェネレーター式と同じであるため、実際には内部でセットにすることはできません。filter
速度を確認するために次のテストを実行しました。
import time
def test ( n, seq ):
for method in ( set, list, tuple ):
t = time.time()
for i in range( n ):
method( seq )
print( method.__name__, ( time.time() - t ) )
someFilter = filter( lambda x: x % 3 == 0, range( 1000 ) )
test( 10000000, someFilter )
そして、結果はセットを使用するために明確に話していました:
set 1.9240000247955322
list 8.82200002670288
tuple 7.031999826431274
では、なぜフィルターからセットを作成する方がはるかに速いのでしょうか。通常、すべての要素をハッシュする必要があるシーケンスからセットを作成するのと同じくらい時間がかかるべきではありませんか?それとも、内部フィルター表現から何らかの形で後押しを得ているのでしょうか?
比較のために、range
式でテストを実行する場合、とのset
約2倍の時間がかかります(どちらも速度はほぼ同じです)。list
tuple
編集:
Svenの答えは完全に正しいですが、完全を期すために、実際のフィルターで実行される更新されたテストは次のとおりです。
import time
def testFilter ( n, test, rangeSize ):
for method in ( set, list, tuple ):
t = time.time()
for i in range( n ):
method( filter( test, range( rangeSize ) ) )
print( method.__name__, ( time.time() - t ) )
testFilter( 100000, lambda x: x % 3 == 0, 1000 )
結果は、実際には何がより理にかなってlist
おり、tuple
両方が最速であることを示していますが、セットは実際には遅くはないので、何を使用しても違いはありません。
set 27.868000030517578
list 27.131999969482422
tuple 27.138000011444092