haskell - 截断到单词类型

  显示原文与译文双语对照的内容
0 0

下面的代码类型的digits是一个数字 Double为域控制器类型 Word16( 虽然我怀疑任何一个word类型的行为类似,我不得不选择一个示例) 。

truncate1 :: Double -> Word16
truncate1 = fromIntegral . (truncate :: Double -> Int)

你可以先看看,我将其截断,以 Int当且仅当我将它强制转换为 Word16. 我校验了这个函数agains直接截断:

truncate2 :: Double -> Word16
truncate2 = truncate

令人惊讶的是,对我来说,第一个版本( 要一只普通的 Int更好的执行优先) 类型。 还是第二个要糟糕得多。 根据标准输出:

benchmarking truncate/truncate1
mean: 25.42399 ns, lb -47.40484 ps, ub 67.87578 ns, ci 0.950
std dev: 145.5661 ns, lb 84.90195 ns, ub 244.2057 ns, ci 0.950
found 197 outliers among 100 samples (197.0%)
  97 (97.0%) low severe
  100 (100.0%) high severe
variance introduced by outliers: 99.000%
variance is severely inflated by outliers
benchmarking truncate/truncate2
mean: 781.0604 ns, lb 509.3264 ns, ub 1.086767 us, ci 0.950
std dev: 1.436660 us, lb 1.218997 us, ub 1.592479 us, ci 0.950
found 177 outliers among 100 samples (177.0%)
  77 (77.0%) low severe
  100 (100.0%) high severe
variance introduced by outliers: 98.995%
variance is severely inflated by outliers

使用Criterion老实说,我刚开始使用它,所以我不是专家,但我理解, 25.42399 ns较短的执行时间比 781.0604 ns. 我怀疑某些专业化的在这里扮演着重要的角色。 就这样 truncate2速度太慢? 既然如此,可以 truncate会提高? 另外,有没有人知道一种更快捷的方法? 我觉得我做错了转换为类型其实并不使用。

感谢你提前。

我是用GHC编译7 .4 .2,启用优化( -O2) 。

时间:原作者:1个回答

0 0

首先,注意路径中的模块。 GHC.Word包括以下RULEpragma :

"truncate/Double->Word16"
    forall x. truncate (x :: Double) = (fromIntegral :: Int -> Word16) (truncate x)

这是一个简单的重写规则,以执行精确的优化你的 truncate1提供。 所以我们需要考虑几个问题:

为什么这个优化点?

因为的默认实现 truncate为泛型方法,支持任意 Integral实例。 你所看到的速度差的成本是普遍性的截断一个基元类型转换为另一种类型,有更快的方法,在特定的情况下使用。

这样看来, truncate1时是一种特殊形式中获益, truncate2不是。

为什么 truncate1快点?

InGHC.Float,其中, RealFrac实例。 Double是,我们有下面的定义 RULEpragma :

"truncate/Double->Int"              truncate = double2Int

其中 double2Int这是我们想要优化形式。 为进行比较, RULE前面提到的显然没有类似的专门用于转换原语操作 DoubleWord16.

为什么不 truncate2会重写为好?

Quoth " GHC User Guide :

ghc当前使用非常简单,语法,LHS与表达式匹配的算法是否有匹配的规则。 它要求一个替换使得categorydiscriminant LHS和表达式在语法上对alpha转换。 pattern ( 规则),但不复制表达式,必要时将巴斯克家园与自由组织展开的。

要不马上就展开,也就是说,它匹配一个规则表达式匹配上 forall x. foo x将匹配在 bar y = foo y不是bar = foo.

因为你的定义都写点免费的, RULEDouble -> Int匹配上,但是。 RULEDouble -> Word16不支持。

原作者:
...