私はBenchfellaを使用していくつかの簡単なベンチマークを実行しようとしました:リストを連結しているのにEnum.concatの方がはるかに遅いのはなぜですか?
defmodule ConcatListBench do
use Benchfella
@a1 Enum.to_list(1..10_000)
@a2 Enum.to_list(10_000..20_0000)
bench "++" do
@a1 ++ @a2
end
bench "Enum.concat" do
Enum.concat(@a1, @a2)
end
end
そして、それを実行している間:
$ elixir -v
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.4.0-dev (762e7de)
$ mix bench
Settings:
duration: 1.0 s
## ConcatListBench
[10:01:09] 1/2: ++
[10:01:20] 2/2: Enum.concat
Finished in 14.03 seconds
## ConcatListBench
benchmark na iterations average time
++ 1000000000 0.01 µs/op
Enum.concat 50000 45.03 µs/op
質問はEnum.concat
が(4K倍以上)遅くなる可能性がどのようであるため、内部it uses++
オペレータた場合リスト?
私はEnum.concat
のガード句とパターンマッチングに時間がかかることを理解していますが、ベンチマークは大きな違いを示していますか?
UPDATE:これは、コンパイル時に最適化され、実行される瞬間の時間を要する++
を使用して、原因Constant Foldingに連結を発生します。したがって、ベンチマークはあまり現実的ではありません。
'Enum.concat'は何にでも作用するので、' enumerable'プロトコルと 'concat'コストのパターンマッチングを実装します。 – mudasobwa
はい、しかし、私はそれが4k倍遅くなるとは思わない...おそらくベンチマークはかなりappositeではない。 –
'List#++/2'は文字通り何も費やさないので、4k倍遅くなります。パターンマッチングを比較する可能性がありますが、そのコストは[もちろんではありません] 'noop'と比較されます。 – mudasobwa