Save @btime output

Is there a simple way to do this?

I just want to save the time n in milliseconds e.g. n = @btime foo for some benchmark like:

check = nothing

function checkaaa()
    rand(10) * rand(10)'
    return nothing
end

check = @btime checkaaa()
@test check !== nothing

julia> @test check !== nothing
Test Failed at REPL[397]:1
  Expression: check !== nothing
   Evaluated: nothing !== nothing
ERROR: There was an error during testing

@btime just prints the result (just like @time). If you want something back you should use @benchmark:

julia> using BenchmarkTools

julia> b = @benchmark rand(2,2);

julia> b
BenchmarkTools.Trial: 
  memory estimate:  112 bytes
  allocs estimate:  1
  --------------
  minimum time:     40.862 ns (0.00% GC)
  median time:      43.809 ns (0.00% GC)
  mean time:        46.494 ns (1.74% GC)
  maximum time:     430.152 ns (88.88% GC)
  --------------
  samples:          10000
  evals/sample:     988

julia> min = minimum(b)
BenchmarkTools.TrialEstimate: 
  time:             40.862 ns
  gctime:           0.000 ns (0.00%)
  memory:           112 bytes
  allocs:           1

julia> min.time
40.86234817813765
11 Likes

excellent, thanks

Note that you can directly use @btime to directly get the timing:

julia> using BenchmarkTools

julia> minimum(@benchmark(rand(2,2))).time / 1e9
4.744287158746209e-8

julia> @belapsed rand(2,2)
4.755668016194332e-8
5 Likes

What if I want both the operation result and the timing? In other words, is there an equivalent of @timed in BenchmarkTools?

This is asked every other week, so probably we should have it directly in BenchmarkTools:

julia> @eval BenchmarkTools macro btimed(args...)
           _, params = prunekwargs(args...)
           bench, trial, result = gensym(), gensym(), gensym()
           trialmin, trialallocs = gensym(), gensym()
           tune_phase = hasevals(params) ? :() : :($BenchmarkTools.tune!($bench))
           return esc(quote
               local $bench = $BenchmarkTools.@benchmarkable $(args...)
               $BenchmarkTools.warmup($bench)
               $tune_phase
               local $trial, $result = $BenchmarkTools.run_result($bench)
               local $trialmin = $BenchmarkTools.minimum($trial)
               $result, $BenchmarkTools.time($trialmin)
           end)
       end
@btimed (macro with 1 method)

julia> BenchmarkTools.@btimed sin(12.3)
(-0.26323179136580094, 1.41)

(the time is returned in nanoseconds)

8 Likes

Thanks! Personally, given how much I rely on @timed, having it in BenchmarkTools would be extremely convenient.

Or also using a custom macro with what one needs…

julia> using BenchmarkTools
julia> macro binfo(bexpr)
           runexpr = quote
             b = @benchmark $bexpr
             return  (median(b).time, median(b).memory, median(b).allocs)
           end
           return eval(runexpr)
       end
@binfo (macro with 1 method)
julia> res = @binfo rand(2,2)
(91.87983706720978, 96, 1)
2 Likes