Я попытался выполнить быстрый бенчмаркинг с помощью Benchfella:
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 раз), если он использует ++
оператор внутри для списков?
Я понимаю, что предложения охраны в Enum.concat
и сопоставлении шаблонов некоторое время, но эта таблица показывает большую разницу, не так ли?
ОБНОВЛЕНИЕ: Это происходит из-за Constant Folding, объединение с использованием ++
оптимизировано во время компиляции и мгновенно принимает время для запуска. Таким образом, эталон не совсем реалистичен.