【发布时间】:2015-09-07 12:38:16
【问题描述】:
更新:Elixir 并不慢,我的算法很慢。我的算法甚至不是苹果对苹果的比较。有关 Ruby 和 Go 等效算法的信息,请参阅下面的 Roman 的答案。还要感谢 José,只需添加 MIX_ENV=prod 前缀就可以显着加快我的慢速算法。我已经更新了问题中的统计信息。
原问题: 我正在研究多种语言的 Project Euler 问题,只是为了看看语言的效率和速度。在problem #5 中,我们被要求找到能被 1 到 20 的所有数字整除的最小正数。
我以多种语言实现了该解决方案。以下是统计数据:
- 去 1.4.2 : 0.58s
- Ruby 2.2 MRI:6.7 秒
- Elixir 1.0.5(我的第一个算法):57s
- Elixir 1.0.5(我的第一个带有 MIX_ENV=prod 前缀的算法):7.4s
- Elixir 1.0.5(Roman's Go 等效算法):0.7s
- Elixir 1.0.5(Roman 的 Ruby 等效算法):1.8s
为什么 Elixir 的性能这么慢?我尝试在所有语言中使用相同的优化。警告:我是 FP 和 Elixir 新手。
我可以做些什么来提高 Elixir 的性能?如果您使用任何分析工具来找出更好的解决方案,您能否将它们包括在响应中?
在围棋中:
func problem005() int {
i := 20
outer:
for {
for j := 20; j > 0; j-- {
if i%j != 0 {
i = i + 20
continue outer
}
}
return i
}
panic("Should have found a solution by now")
}
在 Ruby 中:
def self.problem005
divisors = (1..20).to_a.reverse
number = 20 # we iterate over multiples of 20
until divisors.all? { |divisor| number % divisor == 0 } do
number += 20
end
return number
end
在灵药中:
def problem005 do
divisible_all? = fn num ->
Enum.all?((20..2), &(rem(num, &1) == 0))
end
Stream.iterate(20, &(&1 + 20))
|> Stream.filter(divisible_all?)
|> Enum.fetch! 0
end
【问题讨论】:
-
我无法解释你的 Elixir,但几乎可以肯定有更好的方法来解决这个问题,例如尝试构建数字,而不是仅仅扫描它。
-
谢谢,鲁普。我会试试这个建议。但是,我在这里的问题纯粹与类似逻辑的性能有关,是 3 种不同的语言。
-
如果您对 Elixir 代码进行基准测试,请确保使用 MIX_ENV=prod 对其进行基准测试,以便 Elixir 尽可能高效地编译您的项目。否则,您将获得次优性能。
标签: performance elixir numerical-computing