指数运算符性能

时间:2011-10-25 21:29:34

标签: haskell

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

我遇到了一个有趣的观察,并希望有人可以解释为什么事情就像他们一样。

供参考,我正在实施Problem #29 这就是我的意思

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

我发现使用^^运算符的速度比**快,这比上面列出的输入快^

我的问题很简单,为什么?这些运算符中的每一个都适用于不同的类型。我的猜测是有一些类型的转换正在发生,但我希望^更快的操作,当它看起来实际上是对话时。

谢谢!

3 个答案:

答案 0 :(得分:4)

**^^正在使用Double,但^正在使用Integer。你真的无法将浮点运算与大整数函数进行比较。看看implementation of ^

在您的代码中,以下情况属实:

  • **在硬件中实现。
  • ^在尾递归循环中使用大Integer
  • ^^是相同的,但Double除外。

所以你对他们相对表现的观察是有道理的。

答案 1 :(得分:4)

所有时间都用在nub上。使用^^**,您在nub上正在[Double]^ nub [Integer]上{{1}},比较大整数比比较双倍慢。

答案 2 :(得分:1)

我在解决Project Euler问题时发现的事情是类型可以在运行时性能上产生巨大差异。例如:

foo :: Integral a => a -> a
foo' :: Integer -> Integer
foo'' :: Int -> Int

所有表现都非常不同。想象一下,当我发现简单地让编译器推断出foo的最通用类型而不是自己指定它时,我感到惊讶的是导致性能不佳。

性能(显然)高度依赖于您的环境:您是在运行编译还是解释?优化还是未优化?关键在于,在某些情况下,你可能有未装箱的原始Int#,而不是盒装的,堆分配的值...不幸的是我自己还是一个n00b,我不知道什么时候你会得到一个与另一个:(

所以,这可能是一个愚蠢的答案,但是如果您使用GHC并且熟悉C编程,请尝试使用-keep-hc-files标志来比较使用{{1时生成的中间C代码} {} ^^^