У меня есть этот код:
for i in 1 .. 10 do
let (tree, interval) = time (fun () -> insert [12.; 6. + 1.0] exampletree 128.)
printfn "insertion time: %A" interval.TotalMilliseconds
()
с функцией, определяемой времени как
let time f =
let start = DateTime.Now
let res = f ()
let finish = DateTime.Now
(res, finish - start)
функциональная вставка не релевантна здесь кроме того, что она не использует мутацию и таким образом возвращает то же значение каждый раз.
Я получаю результаты:
insertion time: 218.75
insertion time: 0.0
insertion time: 0.0
insertion time: 0.0
insertion time: 0.0
insertion time: 0.0
insertion time: 0.0
insertion time: 0.0
insertion time: 0.0
insertion time: 0.0
Вопрос состоит в том, почему код вычисляет результат только однажды (со времени вставки, результат всегда корректен и равен)? Кроме того, как вынудить программу сделать вычисление многократно (мне нужно это в профильных целях)?
Править: Jared предоставил правильный ответ. Теперь, когда я знаю, что искать, я могу получить код секундомера от функции timeit для F#
У меня были следующие результаты:
insertion time: 243.4247
insertion time: 0.0768
insertion time: 0.0636
insertion time: 0.0617
insertion time: 0.065
insertion time: 0.0564
insertion time: 0.062
insertion time: 0.069
insertion time: 0.0656
insertion time: 0.0553
F # не выполняет автоматическую мемоизацию ваших функций. В этом случае запоминание было бы некорректным. Даже если вы не изменяете элементы напрямую, вы получаете доступ к изменяемому значению ( DateTime.Now
) из вашей функции. Запоминание этого или функции, обращающейся к нему, было бы ошибкой, поскольку оно может меняться от вызова к вызову.
То, что вы здесь видите, является результатом работы JIT .Net.При первом запуске функция f () выполняется JIT и производит заметную задержку. В других случаях он уже выполняется JIT и выполняет время, меньшее, чем гранулярность DateTime
. Один из способов доказать это - использовать более гранулярный класс измерения, такой как StopWatch
. Это покажет, что функция выполняется много раз.
Первый тайминг, вероятно, связан с JIT-компиляцией. Фактический код, который вы синхронизируете, вероятно, выполняется за меньшее время, чем может измерить DateTime.
Править: Избили на 18 секунд ... Я просто рад, что у меня появилась правильная идея :)