raa*_*cer 6 performance count elixir
我发现计算Enum.map |> Enum.sum的速度要快得多Enum.count.但为什么内置计数功能不高效呢?
比较这两行:
elements |> Enum.count(&check/1)
elements |> Enum.map(&(if check(&1), do: 1, else: 0)) |> Enum.sum
Run Code Online (Sandbox Code Playgroud)
不同长度列表的测试结果:
len | map(), µs | count(), µs
===============================
10 | 0.67 | 2.55
100 | 5.52 | 8.91
1000 | 59.00 | 73.12
10000 | 642.50 | 734.60
Run Code Online (Sandbox Code Playgroud)
源代码:https://gist.github.com/artemrizhov/fc146f7ab390f7a807be833099e5cb83
$ elixir --version
Erlang/OTP 19 [erts-8.1] [source-e7be63d] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]
Elixir 1.3.4
Run Code Online (Sandbox Code Playgroud)
mic*_*ala 16
这是因为两者Enum.map/2和Enum.reduce/3(由sum它们使用)都针对列表进行了大量优化,而Enum.count/2只有一个通用的可枚举版本.
更令人困惑的是,实施起来更快:
elements |> Enum.filter(&check/1) |> Enum.count
Run Code Online (Sandbox Code Playgroud)
在我的机器上,使用您提供的修改基准,我得到了一致的结果:
len = 10
map: 2.1706 ?s
count: 7.0754 ?s
filter: 1.9765 ?s
len = 100
map: 19.921 ?s
count: 27.579 ?s
filter: 14.591 ?s
len = 1000
map: 168.93 ?s
count: 178.93 ?s
filter: 163.43 ?s
len = 10000
map: 2128.9 ?s
count: 1822.1 ?s
filter: 1664.6 ?s
Run Code Online (Sandbox Code Playgroud)
这就是说"map"和"filter"版本在运行时会产生更多的垃圾,因此延长的垃圾收集时间可能会消耗一些时间增益.这在基准测试中已经可见,因为版本之间的相对增益随着列表长度的长度(以及产生的中间垃圾量)的增加而减少.
编辑:我提交了一个PR,优化Enum.count/2了最快的功能https://github.com/elixir-lang/elixir/pull/5567
| 归档时间: |
|
| 查看次数: |
1403 次 |
| 最近记录: |