Прежде всего, осознайте, что GHCi является переводчиком, и он не предназначен для очень быстрой работы.Чтобы получить более полезные результаты, вы должны скомпилировать код с включенной оптимизацией.Это может иметь огромное значение.
Кроме того, для любого серьезного бенчмаркинга кода на Haskell я рекомендую использовать критерий .Он использует различные статистические методы, чтобы гарантировать, что вы получаете надежные измерения.
Я изменил ваш код, чтобы использовать критерий, и удалил операторы печати, чтобы мы не синхронизировали ввод-вывод.
import Criterion.Main
import Data.Vector as V
vector :: IO (Vector Int)
vector = do
let vec = V.replicate 3000000 10
return vec
sumit :: IO Int
sumit = do
vec <- vector
return $ V.sum vec
main = defaultMain [bench "sumit" $ whnfIO sumit]
Скомпилировав это с -O2
, я получаю результат на довольно медленном нетбуке:
$ ghc --make -O2 Sum.hs
$ ./Sum
warming up
estimating clock resolution...
mean is 56.55146 us (10001 iterations)
found 1136 outliers among 9999 samples (11.4%)
235 (2.4%) high mild
901 (9.0%) high severe
estimating cost of a clock call...
mean is 2.493841 us (38 iterations)
found 4 outliers among 38 samples (10.5%)
2 (5.3%) high mild
2 (5.3%) high severe
benchmarking sumit
collecting 100 samples, 8 iterations each, in estimated 6.180620 s
mean: 9.329556 ms, lb 9.222860 ms, ub 9.473564 ms, ci 0.950
std dev: 628.0294 us, lb 439.1394 us, ub 1.045119 ms, ci 0.950
Таким образом, я получаю среднее значение чуть более 9 мс со стандартным отклонением менее чеммиллисекунды.Для более крупного тестового случая я получаю около 100 мс.
Включение оптимизации особенно важно при использовании пакета vector
, поскольку он интенсивно использует stream fusion , который в этомcase может полностью исключить структуру данных, превратив вашу программу в эффективный, плотный цикл.
Возможно, стоит поэкспериментировать с новым генератором кода на основе LLVM, используя опцию -fllvm
. По-видимому, хорошо подходит для числового кода .