当我第一次搜索我的代码很慢的地方时,我真的很惊讶,没有预料到这一点,那就是动力(或乘法) 可以更快,因此班次代码中的某些内容非常慢。
(整数)供电的代码
{-# OPTIONS_GHC -O2 #-}
import System.Environment(getArgs)
main = do
[a,b] <- getArgs
let c = ( read a::Integer ) ^ ( read b::Int )
print ( mod c 2 )
转移的示例代码
{-# OPTIONS_GHC -O2 #-}
import Data.Bits
import System.Environment(getArgs)
main = do
[a,b] <- getArgs
let c = shift ( read a::Integer ) ( read b::Int )
print( mod c 2 )
我在旧的和最新的haskell上运行:
c:\ ghc \ ghc-6.10.4 \ bin&gt; cmd / v:on / c“echo!TIME!&amp; pow.exe 33 40000000&amp; echo!TIME!”
1:24:29,02
1
1:24:41,48
- 12.46秒供电
c:\ ghc \ ghc-6.10.4 \ bin&gt; cmd / v:on / c“echo!TIME!&amp; shift.exe 3 200000000&amp; echo!TIME!”
1:27:08,76
0
1:27:22,06
- 13.30秒转移
c:\ ghc \ ghc-7.6.3 \ bin&gt; cmd / v:on / c“echo!TIME!&amp; pow.exe 33 40000000&amp; echo!TIME!”
2:19:29,39
1
2:19:37,06
- 7.67秒用于供电(因此供电有所改善)
c:\ ghc \ ghc-7.6.3 \ bin&gt; cmd / v:on / c“echo!TIME!&amp; shift.exe 3 200000000&amp; echo!TIME!”
2:20:49,61
0
2:20:49,69
- 0.08秒用于转移(这意味着加速大约为150)
或甚至(此处20亿位移位):
c:\ ghc \ ghc-7.6.3 \ bin&gt; cmd / v:on / c“echo!TIME!&amp; shift.exe 3 2000000000&amp; echo!TIME!”
3:07:22,05
0
3:07:22,56
- 0.51秒
在跑步中,数字非常大,看起来运行时间很长。 在第一个代码中,我们计算33 ^ 40000000(mod 2),在第二个代码中3 * 2 ^ 200000000(mod 2)。模组 操作(或其他东西)必须要看到不是0时间(因为在这种情况下haskell不会计算它)。如上所述 供电速度更快,并且还注意到在这种情况下33 ^ 40000000大于3 * 2 ^ 200000000。 此外,在内存使用方面,您可以看到最新的haskell也计算了3 ^ 200000000,因此没有深度优化技巧 这里。
是否有可能在这个旧的haskell版本中获得加速?我有兴趣在两个方向上移动(大整数), 我们可以假设我们以64位的倍数(或63或32或31;在haskell上的整数表示中的单词大小)移位, 所以没有环绕。
尝试计算2 ^ n然后执行乘法(或除法)来进行移位,但它没有给旧的haskell加速。
UPDATE
使用-v标志运行编译器开始打印:(我也可以发布其余的)格拉斯哥Haskell编译器,版本6.10.4,适用于Haskell 98,第2阶段由GHC版本6.10.1启动
使用包配置文件:C:\ ghc \ ghc-6.10.4 \ package.conf
隐藏包base-3.0.3.1以避免与更高版本base-4.1.0.0冲突
接线包ghc-prim映射到ghc-prim-0.1.0.0
有线包整数映射到整数-0.0.0.1
有线包基地映射到base-4.1.0.0
有线包rts映射到rts-1.0
有线包haskell98映射到haskell98-1.0.1.0
有线包syb映射到syb-0.1.0.1
有线包模板-haskell映射到template-haskell-2.3.0.1
有线包dph-seq映射到dph-seq-0.3
有线包dph-par映射到dph-par-0.3
Hsc静态标志:-static