我试着用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'可以用于任何事情,在'concat'成本中实现'Enumerable'协议和模式匹配。 – mudasobwa
是的,但我不认为它会慢4k倍...也许基准测试不太合适。 –
因为'List#++/2'几乎没有成本,所以它慢了4k倍。您可能会比较模式匹配,这会造成[当然不是]'noop'的成本。 – mudasobwa