使用GHC 7.0.3
,gcc 4.4.6
,Linux 2.6.29
一个x86_64的Core2双核(2.5GHz的)机器上,编译使用ghc -O2 -fllvm -fforce-recomp
用于Haskell和gcc -O3 -lm
为C.
factorCount'
不断应用两个永不改变的自变量(number
,sqrt
)。工人/包装工人的转型为我们提供了:
$ time ./so 842161320
real 0m7.954s user 0m7.944s sys 0m0.004s
没错, 。始终 。没有-fllvm
标记,我仍然会收到消息8.182 seconds
,因此NCG后端在这种情况下也表现良好。
结论:Haskell很棒。
factorCount number = factorCount' number isquare 1 0 - (fromEnum $ square == fromIntegral isquare)
where square = sqrt $ fromIntegral number
isquare = floor square
factorCount' :: Int -> Int -> Int -> Int -> Int
factorCount' number sqrt candidate0 count0 = go candidate0 count0
where
go candidate count
| candidate > sqrt = count
| number `rem` candidate == 0 = go (candidate + 1) (count + 2)
| otherwise = go (candidate + 1) count
nextTriangle index triangle
| factorCount triangle > 1000 = triangle
| otherwise = nextTriangle (index + 1) (triangle + index + 1)
main = print $ nextTriangle 1 1
编辑:现在,我们已经探索了这一点,让我们解决问题
问题1:erlang,python和haskell是否会由于使用任意长度的整数而导致速度下降,还是只要它们的值小于MAXINT,它们就不会丢失吗?
在Haskell中,使用Integer
的速度慢于Int
但要慢多少,取决于执行的计算。幸运的是(对于64位计算机)Int
就足够了。出于可移植性考虑,您可能应该重写我的代码以使用Int64
或Word64
(C不是唯一带有的语言long
)。
问题2:为什么haskell这么慢?是否有编译器标志可以使您刹车?或者这是我的实现?(后者很可能因为haskell是一本对我有七个印章的书。)
问题3:能否为我提供一些提示,说明如何在不改变确定因素的方式下优化这些实现?以任何方式进行优化:对语言更好,更快,更“原生”。
那就是我上面回答的。答案是
问题4:我的功能实现是否允许LCO,从而避免在调用堆栈中添加不必要的帧?
是的,这不是问题。做得好,很高兴您考虑了这一点。