2011-10-25 66 views
4

好吧,也許這裏一個愚蠢的問題,但我目前通過完成projecteuler.net指數經營者業績

我遇到了一個有趣的觀察問題的學習Haskell和希望有人能提供一些線索爲什麼事情的方式,他們是。

僅供參考,我正在執行Problem #29 這裏就是我想出了

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

我觀察到使用^^操作快於**^上面列出的輸入速度更快。

我的問題很簡單,爲什麼?每個這些運算符都適用於不同的類型類別。我的猜測是發生了一些類型轉換,但我認爲^是更快的操作,當它看起來實際上是反例。

謝謝!

+1

如果列表不是很短(這是不是),不要使用結點,這是O(n^2)。 –

+3

有Haskell中沒有類型轉換。 –

回答

4

所有的時間都花在nub上。隨着^^**你在[Double]上做nub。與^它是nub[Integer],比較大整數慢於比較雙打。

+0

對,'nub'在這個例子中做了所有的工作,謝謝你的解釋。 – Jake

4

**^^正在使用Double,但^正在使用Integer。你真的無法將浮點運算與大整數函數進行比較。看看implementation of ^

在你的代碼,以下是真:

  • **在硬件中實現。
  • ^在尾遞歸循環中使用大Integer
  • ^^是一樣的,除了Double

因此,你對他們的相對錶現的觀察是有道理的。

1

我在處理Project Euler問題時發現的事情是,類型可以使運行時性能發生巨大變化。例如:

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

都有很不同的表現。想象一下,當我發現簡單地讓編譯器推斷出foo的最通用類型,而不是自己指定它,導致性能較差時,我很驚訝。

性能也(顯然)高度依賴於您的環境:您正在運行編譯或解釋?優化還是未優化?問題是,在某些情況下,你可能已經拆箱,原始的Int# s在封面下而不是裝箱,堆分配值...不幸的是,我仍然足夠的一個n00b我自己,我不知道你什麼時候會得到一個vs.其他:(

所以,也許這是一個愚蠢的答案,但如果你使用GHC和你熟悉C語言編程,嘗試使用-keep-hc-files標誌當您使用^比較它們生成的中間的C代碼。^^**

+0

當編譯器看到Ints是嚴格需要的時候,你會得到Int#,你可以幫助使用爆炸模式,但是檢查覈心是否你有他們,並衡量它是否真的有幫助另一個說明,.hc文件只能由未註冊的編譯器生成(用戶指南),所以大多數人都不會擁有它們。 –