Принудительная оценка входных данных функции перед тестированием в Criterion

Как принудительно выполнить оценку входных данных функции перед тестированием функции в Критерии ? Я пытаюсь протестировать некоторые функции, но хочу исключить время для оценки входного преобразователя. В рассматриваемом коде для ввода используются распакованных векторов , которые не могут быть глубокими для векторов Int . Пример фрагмента кода ниже:

-- V is Data.Vector.Unboxed
shortv = V.fromList [1..10] :: V.Vector GHC.Int.Int16
intv = V.fromList [1..10] :: V.Vector GHC.Int.Int32

main :: IO ()
main = defaultMain [
          bench "encode ShortV" $ whnf encodeInt16V shortv
          ,bench "encode IntV" $ whnf encodeInt32V intv
       ]

Тест Criterion включает время для создания входных данных shortv и intv при тестировании вышеуказанных функций. Измерения критериев приведены ниже - он измеряет около ~ 400 нс для каждой функции, что, кажется, также включает время сборки для входных данных:

benchmarking encode ShortV
mean: 379.6917 ns, lb 378.0229 ns, ub 382.4529 ns, ci 0.950
std dev: 10.79084 ns, lb 7.360444 ns, ub 15.89614 ns, ci 0.950

benchmarking encode IntV
mean: 392.2736 ns, lb 391.2816 ns, ub 393.4853 ns, ci 0.950
std dev: 5.565134 ns, lb 4.694539 ns, ub 6.689224 ns, ci 0.950 

Теперь, если основной раздел кода теста изменен на приведенный ниже (путем удаления второй функции теста):

main = defaultMain [
          bench "encode ShortV" $ whnf encodeInt16V shortv
       ]

Кажется, что ввод shortv оценивается перед тестированием функции encodeInt16V. Это действительно желаемый результат для меня, потому что этот тест измеряет время выполнения функции, исключая время для создания ввода. Результат ниже:

benchmarking encode ShortV
mean: 148.8488 ns, lb 148.4714 ns, ub 149.6279 ns, ci 0.950
std dev: 2.658834 ns, lb 1.621119 ns, ub 5.184792 ns, ci 0.950

Точно так же, если я тестирую только тест «encode IntV», я получаю время ~ 150 нс и для этого.

Из документации Criterion я знаю, что он пытается избежать ленивой оценки для более точного тестирования. Это имеет смысл и здесь не проблема.Мой вопрос в том, как мне создать входные данные shortv и intv, чтобы они уже оценивались перед передачей в функцию тестирования. Прямо сейчас я могу добиться этого, ограничив defaultMain тестированием только одной функции за раз (как я только что показал выше), но это не идеальное решение.

EDIT1

Что-то еще происходит с тестом Criterion, и, похоже, это происходит только с векторным массивом, а не со списками. Если я принудительно выполню полную оценку, напечатав shortv и intv, тест по-прежнему измеряет время как ~ 400 нс, а не ~ 150 нс. Обновление кода ниже:

main = do
  V.forM_ shortv $ \x -> do print x
  V.forM_ intv $ \x -> do print x
  defaultMain [
          bench "encode ShortV" $ whnf encodeInt16V shortv
          ,bench "encode IntV" $ whnf encodeInt32V intv
       ]

Вывод критерия (также имеет 158,4% выбросов, что кажется неправильным):

estimating clock resolution...
mean is 5.121819 us (160001 iterations)
found 253488 outliers among 159999 samples (158.4%)
  126544 (79.1%) low severe
  126944 (79.3%) high severe
estimating cost of a clock call...
mean is 47.45021 ns (35 iterations)
found 5 outliers among 35 samples (14.3%)
  2 (5.7%) high mild
  3 (8.6%) high severe

benchmarking encode ShortV
mean: 382.1599 ns, lb 381.3501 ns, ub 383.0841 ns, ci 0.950
std dev: 4.409181 ns, lb 3.828800 ns, ub 5.216401 ns, ci 0.950

benchmarking encode IntV
mean: 394.0517 ns, lb 392.4718 ns, ub 396.7014 ns, ci 0.950
std dev: 10.20773 ns, lb 7.101707 ns, ub 17.53715 ns, ci 0.950

6
задан Sal 5 December 2011 в 00:55
поделиться