Algorithm 在Haskell中实现Karatsuba算法

Algorithm 在Haskell中实现Karatsuba算法,algorithm,haskell,multiplication,Algorithm,Haskell,Multiplication,我刚刚了解了Karatsuba算法,并尝试在Haskell中实现它 这是我的密码: (***) :: Integer -> Integer -> Integer x *** y | max x y < ub = x*y | otherwise =z2*base*base + ((x1+x0)***(y1+y0)-z2-z0)*base + z0 where base =10^((length . show $ ma

我刚刚了解了Karatsuba算法,并尝试在Haskell中实现它

这是我的密码:

(***) :: Integer -> Integer -> Integer
x *** y
    | max x y < ub = x*y    
    | otherwise =z2*base*base + ((x1+x0)***(y1+y0)-z2-z0)*base + z0
        where
            base =10^((length . show $ max x y) `div` 2)
            z2 =x1***y1
            z0 = x0***y0
            (x1, x0) = helper x
            (y1, y0) = helper y
            helper n = (n `div` base, n `mod` base)
            ub = 10000
(***)::整数->整数->整数
x***y
|最大x y

只要我使用20-30位这样的大数字进行检查,并且速度足够快,可以满足10-20位的要求,这种方法就可以准确地工作。然而,当使用100位数字或更大的数字时,这比正常的
*
要慢得多。如何改进这个算法

事实上,我怀疑你能否提高性能,打败天真的操作符Haskell use the hood,当算法在值范围内运行良好时,它应该自动使用Toom-3或其他算法。天真的Karatsuba甚至可能不会被使用,但据说Toom系列在算法上与之非常接近。如果你仔细想想,GHC没有理由不使用一些先进的乘法算法,因为他们已经开箱即用地支持它了

上次我检查时,GMP的速度非常快,即使在正常的双范围内使用,也至少与gcc的编译结果一样快

有一个关于从GHC中删除GMP的建议,但它似乎相当不活跃


编辑:感谢@danvari,这里是GMP使用的不同算法:。似乎当数字足够小时,Karatsuba也会被使用,除了通常的Toom Cook系列之外,FFT也会被使用。

谢谢你的回答。我懂了。在这种情况下,我的算法还不错,只是
*
真的很快?可能是这样,至少这是我的想法。几年前我用过GMP,发现它很神奇。似乎有很多算法,有相当前沿的研究思路,所以我不希望它轻易被超越。我明白了。嗯,实现算法是一个很好的实践。感谢您的回答。GMP使用以下算法进行整数乘法(按输入数字的大小排序):1。朴素(教科书)算法,2。Karatsuba,3岁。通3路,4路。通4路,5路。更高的学位是6。快速傅立叶变换乘法。这个
base=10^((length.show$max x y)
div`2)`不好。尽管GHC的
Show
实例的
Integer
速度比Java的
biginger.toString()
或Python的
str
要快几个数量级,但这仍然相当慢(想想它必须做些什么)。使用
GHC.Float.integerLogBase
应该可以获得很好的加速。如果你使用2次方的基数可能更好。