更新:Elixir不慢,我的算法才慢。我的算法甚至没有进行苹果对苹果的比较。请查看下面Roman关于Ruby和Go等效算法的回答。还要感谢José,我的慢算法可以通过仅加前缀MIX_ENV=prod显著加速。我已经更新了问题中的数据。
原问题: 我正在使用多种语言解决Project Euler问题,以了解各种语言的生产力和速度。在问题 #5中,我们被要求找到最小的正整数,它能被从1到20的所有数字整除。
我用多种语言实现了解决方案。以下是统计数据:
- Go 1.4.2:0.58秒
- Ruby 2.2 MRI:6.7秒
- Elixir 1.0.5(我的第一个算法):57秒
- Elixir 1.0.5(我的第一个算法加上MIX_ENV=prod前缀):7.4秒
- Elixir 1.0.5(Roman的Go等效算法):0.7秒
- Elixir 1.0.5(Roman的Ruby等效算法):1.8秒
为什么Elixir的性能如此之慢?我尝试在所有语言中使用相同的优化。请注意,我是一个FP和Elixir新手。
有什么办法可以改善Elixir的性能吗?如果您使用任何分析工具来找到更好的解决方案,请在回复中包含它们。
在Go中:
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
在Elixir中:
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