我讀的標準哈斯克爾庫的實現(^)的代碼:的執行情況(^)
(^) :: (Num a, Integral b) => a -> b -> a
x0^y0 | y0 < 0 = errorWithoutStackTrace "Negative exponent"
| y0 == 0 = 1
| otherwise = f x0 y0
where -- f : x0^y0 = x^y
f x y | even y = f (x * x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x * x) ((y - 1) `quot` 2) x
-- g : x0^y0 = (x^y) * z
g x y z | even y = g (x * x) (y `quot` 2) z
| y == 1 = x * z
| otherwise = g (x * x) ((y - 1) `quot` 2) (x * z)
現在這部分,其中G是定義似乎有些奇怪我爲什麼不只是實現它像這個:
expo :: (Num a ,Integral b) => a -> b ->a
expo x0 y0
| y0 == 0 = 1
| y0 < 0 = errorWithoutStackTrace "Negative exponent"
| otherwise = f x0 y0
where
f x y | even y = f (x*x) (y `quot` 2)
| y==1 = x
| otherwise = x * f x (y-1)
但的確如此插入3^1000000顯示(^)大約比展會快0,04秒。
爲什麼
(^)
比expo
更快?
這當然不是一個非常戲劇化的問題,但是我認爲你的版本效率低下的原因是它將小數字「x」與f的一個大的結果進行了很多倍增。標準版本通過在遞歸調用之後一直髮送剩餘因子來生成更平衡的乘法樹。 – leftaroundabout
'g'是尾遞歸,而最後一個'f'不是。我想這裏很重要。 – chi