F# делает автоматический memoisation?

У меня есть этот код:

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

5
задан Community 23 May 2017 в 10:32
поделиться

2 ответа

F # не выполняет автоматическую мемоизацию ваших функций. В этом случае запоминание было бы некорректным. Даже если вы не изменяете элементы напрямую, вы получаете доступ к изменяемому значению ( DateTime.Now ) из вашей функции. Запоминание этого или функции, обращающейся к нему, было бы ошибкой, поскольку оно может меняться от вызова к вызову.

То, что вы здесь видите, является результатом работы JIT .Net.При первом запуске функция f () выполняется JIT и производит заметную задержку. В других случаях он уже выполняется JIT и выполняет время, меньшее, чем гранулярность DateTime

. Один из способов доказать это - использовать более гранулярный класс измерения, такой как StopWatch . Это покажет, что функция выполняется много раз.

16
ответ дан 18 December 2019 в 07:53
поделиться

Первый тайминг, вероятно, связан с JIT-компиляцией. Фактический код, который вы синхронизируете, вероятно, выполняется за меньшее время, чем может измерить DateTime.

Править: Избили на 18 секунд ... Я просто рад, что у меня появилась правильная идея :)

4
ответ дан 18 December 2019 в 07:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: