Следующий код усекает число типа 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
).