以下代码将类型中的多个类型截断Double
为一个Word16
(尽管我怀疑任何其他单词类型的行为相似,但我不得不为示例选择一个)。
truncate1 :: Double -> Word16
truncate1 = fromIntegral . (truncate :: Double -> Int)
如您所见,我首先将其截断为Int
,然后才将其转换为Word16
. 我将此函数与直接截断进行了基准测试:
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
)。