3
予想通りf1
は,、f2
はO(i・log i)です。ここで何が起こっているのですか?ハスケル:Data.Set `notMember`は` notElem`より遅いですか?
import Data.Set
i = 20000
-- should be slow
f1 = [ x | x <- [1..i] , x `notElem` [2..i-1] ]
-- should be fast
f2 = [ x | x <- [1..i] , x `notMember` fromAscList [2..i-1] ]
GHCiの出力は:
*Main> f1
[1,20000]
(7.12 secs, 16,013,697,360 bytes)
*Main> f2
[1,20000]
(44.27 secs, 86,391,426,456 bytes)
変更が重要であることを確認するのは楽しいので、手動でさまざまな最適化を適用することもできます。私の実験から、重要な2人はセットの定義を解除し、それが単相性であることを確認しています。 ghciで '' 'let s = fromAscList [2..i-1] :: [x | x [ - [1..i]、x 'notMember's]' ''はインスタントで、 '' 'はlet s = [2..i-1] :: [Integer] in [x | x < - [1..i]、x 'notElem's'''はOPのリストベースコードの約2倍の速さですが、' Set'バージョンよりもまだ遅いです。 –
私はそれを解釈するのではなく、コンパイルされたバージョンをロードするために 'ghci -fobject-code'とすべきだと思います。 (もちろんモジュールに 'main'があるので答えには影響しません) – user2407038
@ user2407038オブジェクトファイルがすでにそこにあれば、コンパイルされたバージョンがロードされていると思います。 )。 – Alec