更新:藥劑不慢,我的算法是。我的算法甚至不是蘋果來比較蘋果。有關Ruby和Go等效算法,請參閱下面的羅馬答案。還要感謝José,只需在MIX_ENV = prod的前面加上我的慢速算法即可。我已經更新了問題中的統計數據。爲什麼Elixir在Ruby中最慢並且在解決Project Euler#5方面走得很慢?
原始問題: 我正在研究多種語言的歐拉問題,只是爲了瞭解語言的多產和多快。在problem #5中,我們被要求找到能被1到20中的所有數字均勻劃分的最小正數。
我以多種語言實現瞭解決方案。這裏是統計:
- 轉到1.4.2:0.58s
- 紅寶石2.2 MRI:6.7s
- 藥劑1.0.5(我的第一個算法):57S
- 藥劑1.0.5(我與MIX_ENV =督促前綴第一算法):7.4S
- 藥劑1.0.5(羅馬的Go相當於算法):0.7秒
- 藥劑1.0.5(羅馬的Ruby等效算法):1.8秒
藥劑爲什麼如此緩慢?我嘗試在所有語言中使用相同的優化。警告:我是FP和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
我無法解釋你的靈藥,但幾乎肯定更好的方法來解決這個問題,例如嘗試構建數字而不是僅僅掃描它。 – Rup
謝謝,Rup。我會嘗試這個建議。不過,我這裏的問題純粹涉及到類似邏輯的表現是3種不同的語言。 –
如果您使用Elixir代碼進行基準測試,請確保您使用MIX_ENV = prod進行基準測試,以便Elixir儘可能高效地編譯您的項目。否則,你會獲得不理想的表現。 –