更新:Elixir 并不慢,我的算法是。我的算法甚至不是苹果对苹果的比较。有关 Ruby 和 Go 等效算法的信息,请参阅下面的 Roman 的答案。还要感谢 José,只需添加 MIX_ENV=prod 前缀就可以显着加快我的慢速算法。我已经更新了问题中的统计数据。
原始问题: 我正在研究多种语言的 Project Euler 问题,只是为了看看语言的效率和速度。在问题 #5中,我们被要求找到能被 1 到 20 的所有数字整除的最小正数。
我用多种语言实现了该解决方案。以下是统计数据:
- 去 1.4.2 : 0.58s
- Ruby 2.2 MRI : 6.7s
- Elixir 1.0.5(我的第一个算法):57s
- Elixir 1.0.5(我的第一个带有 MIX_ENV=prod 前缀的算法):7.4s
- Elixir 1.0.5(罗马围棋等效算法):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")
}
在红宝石中:
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