Zulip Chat Archive

Stream: lean4

Topic: Measure compute time


pcpthm (Aug 06 2022 at 10:58):

How to measure the time of pure computation? I can use IO.monoMsNow to get the current time but I need to ensure the computation is done between two calls to the IO.monoMsNow function.

The best I come up with is a "black box" API (α → IO α), like so:

@[noinline] opaque blackBox : α  IO α := pure

def compute : Nat  Nat := sorry -- expensive computation

def func (input : Nat) : IO Nat := do
  let startTime  IO.monoMsNow
  let input  blackBox input
  let output  blackBox $ compute input
  let endTime  IO.monoMsNow
  println! "time: {endTime - startTime}"
  return output

But it relies on the behavior that blackBox is not inlined.

Maybe it doesn't much make sense if α is a singleton type.

Henrik Böving (Aug 06 2022 at 11:32):

You want docs4#timeit, if it's a pure computation you can just Function.comp pure yourFunction

pcpthm (Aug 06 2022 at 12:04):

Unfortunately, timeit doesn't work:

def computeFib (n : Nat) : Nat := Id.run do
  let mut (a, b) := (0, 1)
  for _ in [1:n] do
    (a, b) := ((a + b) % 10000, a)
  return a

def main : IO Unit := do
  let input := ( ( IO.getStdin).getLine).trim.toNat!
  let output  timeit "time" do
    return computeFib input
  println! "{output}"

And input 100000000. The result is time 0.00021ms even though it is actually taking 1s.

I guess this is because computeFib input can be computed before timeit starts.
Thus, to make computation happen inside the timeit block, I need to get input inside the timeit block. However, that means the time it takes to input (waiting for user input) will be counted for the time.

Also, I want to more flexible output than the fixed timeout output.

Sebastian Ullrich (Aug 06 2022 at 12:28):

pcpthm said:

But it relies on the behavior that blackBox is not inlined.

What's the problem with that? It's not really different from https://doc.rust-lang.org/std/hint/fn.black_box.html

pcpthm (Aug 06 2022 at 12:43):

A concern was even if Lean doesn't inline a function, an C compiler will inline the function later. But thinking about that, the C compiler is usually not reordering statements, so it is okay I guess.

I guess, in the end, because computation time is not something semantic, probably there is no way to truly ensure something like this.

pcpthm (Aug 06 2022 at 12:48):

Like, even if blackBox was truly opaque, a hypothetical transformation of code:

do blackBox (compute (<- blackBox input))

to

let precomputedFor0 := compute 0
do match <- blackBox input with
  | 0 => blackBox precomputedFor0
  | input => blackBox (compute input)

is valid and the computation time will be bogus.


Last updated: Dec 20 2023 at 11:08 UTC