Haskell 指数算子性能

Haskell 指数算子性能,haskell,Haskell,好的,也许这是一个愚蠢的问题,但我目前正在通过在projecteuler.net上完成问题来学习haskell 我遇到了一个有趣的观察结果,希望有人能解释为什么事情是这样的 作为参考,我正在实施 这是我想到的 nub $ [ a^^b | a <- [2..100], b <- [2..100] ] nub$[a^^b | a***和^^使用的是双精度,但是^使用的是整数。您确实无法将浮点运算与大整数函数进行比较。请看下面的示例 在您的代码中,以下是正确的: **在硬件中实现 ^

好的,也许这是一个愚蠢的问题,但我目前正在通过在projecteuler.net上完成问题来学习haskell

我遇到了一个有趣的观察结果,希望有人能解释为什么事情是这样的

作为参考,我正在实施 这是我想到的

nub $ [ a^^b | a <- [2..100], b <- [2..100] ]

nub$[a^^b | a
***
^^
使用的是
双精度
,但是
^
使用的是
整数
。您确实无法将浮点运算与大整数函数进行比较。请看下面的示例

在您的代码中,以下是正确的:

  • **
    在硬件中实现
  • ^
    在尾部递归循环中使用大的
    整数
  • ^
    与之相同,只有
    Double
    除外

因此,您对它们的相对性能的观察是有意义的。

所有的时间都花在
nub
上。使用
^
**
您在
[Double]
上做
nub
[Integer]上做
就是
nub
,比较大整数要比比较双倍整数慢。

在处理Project Euler问题时,我发现类型会对运行时性能产生巨大影响。例如:

foo :: Integral a => a -> a
foo' :: Integer -> Integer
foo'' :: Int -> Int
所有这些都有非常不同的性能。当我发现仅仅让编译器推断
foo
的最通用类型而不是自己指定它会导致性能低下时,想象一下我的惊讶吧

性能也是(明显的)高度依赖于您的环境:您正在运行编译或解释?优化还是未优化?问题是,在某些情况下,您可能会将未装箱的原始
Int
s隐藏在封底下,而不是装箱的堆分配值……不幸的是,我自己仍然是n00b的一员,我不知道您何时会得到一个n00b与其他人相比:(


因此,也许这是一个愚蠢的答案,但是如果您使用GHC并且熟悉C编程,请尝试使用
-keep hc files
标志来比较使用
^
^
^
**

时生成的中间C代码。对了,
nub
正在完成示例中的所有工作。感谢您这么做清楚。如果列表不是很短(事实并非如此),请不要使用nub。它是O(n^2)。Haskell中没有类型转换。当编译器发现严格需要Int时,您将得到Int。您可以帮助使用bang模式,但一定要检查核心是否得到了它们,并衡量它是否真的有帮助。另一方面,.hc文件仅由未注册的编译器生成(《用户指南》),所以大多数人无论如何都不会有。