我的第一個真正的編程經驗是Haskell。爲了滿足我的特殊需求,我需要一個易於學習,易於編碼和易於維護的工具,我可以說它很好地完成了這項工作。C vs Haskell Collatz猜想速度比較
然而,我的任務規模變得更大了,我認爲C可能更適合他們,並且確實如此。也許我在編程方面沒有足夠的技巧,但是我沒有把Haskell作爲C的速度效率,儘管我聽說Haskell具有相似的性能。最近,我想我會再次嘗試一些Haskell,雖然它對通用簡單(在計算方面)任務仍然很棒,但似乎無法將C的速度與Collatz猜想等問題相匹配。我已閱讀:
Speed comparison with Project Euler: C vs Python vs Erlang vs Haskell
GHC Optimization: Collatz conjecture
collatz-list implementation using haskell
但是從我所看到的,簡單的優化方法,包括:
- 選擇 「更嚴格的」 類型,如Int64的,而不是Integer
- 車削GHC優化在
- S使用簡單的優化技術,如避免不必要的計算或簡單的功能
還是不要讓Haskell代碼甚至接近幾乎相同(在方法方面)爲真正的大號碼的C代碼。唯一能夠使它的性能與C相當(用於大規模問題)的唯一方法是使用優化方法,使代碼成爲漫長而可怕的monadic地獄,這違背了Haskell(和我)非常重視的原則。
這裏的C版本:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int32_t col(int64_t n);
int main(int argc, char **argv)
{
int64_t n = atoi(argv[1]), i;
int32_t s, max;
for(i = 2, max = 0; i <= n; ++i)
{
s = col(i);
if(s > max) max = s;
}
printf("%d\n", max);
return 0;
}
int32_t col(int64_t n)
{
int32_t s;
for(s = 0; ; ++s)
{
if(n == 1) break;
n = n % 2 ? 3 * n + 1 : n/2;
}
return s;
}
和Haskell的版本:
module Main where
import System.Environment (getArgs)
import Data.Int (Int32, Int64)
main :: IO()
main = do
arg <- getArgs
print $ maxCol 0 (read (head arg) :: Int64)
col :: Int64 -> Int32
col x = col' x 0
col' :: Int64 -> Int32 -> Int32
col' 1 n = n
col' x n
| rem x 2 == 0 = col' (quot x 2) (n + 1)
| otherwise = col' (3 * x + 1) (n + 1)
maxCol :: Int32 -> Int64 -> Int32
maxCol maxS 2 = maxS
maxCol maxS n
| s > maxS = maxCol s (n - 1)
| otherwise = maxCol maxS (n - 1)
where s = col n
TL; DR:是Haskell代碼快速編寫和維護簡單,只爲計算簡單的任務,失去這個性能至關重要時的特點?
我永遠不會懷疑GHC不會優化部門!我使用Windows GHC 7.4.2,所以我想這是第二個問題(它是32位)。你能否指點我一些GHC缺陷的來源(我想它應該被認爲是一個缺陷)? – ljedrz
@ yzb3升級到7.6.1,它有一個適用於Windows的64位版本。儘可能快地升級。是的,就高層次優化而言,GHC是** Awe-so-me **,但在低級優化方面有所欠缺。沒有足夠的人從事這項工作,對語言擴展的需求高於低級別的優化。我知道沒有收集這些弱點,你可以搜索[trac](http://hackage.haskell.org/trac/ghc)獲取各種演出相關的門票,除此之外,我可以給出的最好建議是閱讀核心(和asm,如果可以的話)。 –
讓我們將這個問題歸檔,以顯示非建設性問題可以成爲教學用戶非常有趣的主題。 – David