Benchmarking
This notebook shows some @benchmark
and @code_warntype
output. Both outputs are shown via the with_terminal
from PlutoUI.jl, see below.
We define some function double
and a dictionary of numbers in order to show type inference problems via @code_warntype
:
numbers = Dict(:one => 1f0, :two => 2.0)
Dict{Symbol, AbstractFloat} with 2 entries: :two => 2.0 :one => 1.0
function double(mapping, key::Symbol)
return 2 * mapping[key]
end;
Now, the code works.
double(numbers, :one)
2.0f0
double(numbers, :two)
4.0
But the @code_warntype
shows some big red warnings:
using PlutoUI: with_terminal
with_terminal() do
@code_warntype double(numbers, :one)
end
MethodInstance for Main.var\"workspace#4\".double(::Dict{Symbol, AbstractFloat}, ::Symbol) from double(�[90mmapping�[39m, �[90mkey�[39m::�[1mSymbol�[22m)�[90m @�[39m �[90mMain.var\"workspace#4\"�[39m �[90m~/work/JuliaTutorialsTemplate/JuliaTutorialsTemplate/tutorials/�[39m�[90m�[4mbenchmarking.jl#==#3f0e2049-8597-4dac-b499-4d7a8a35978e:1�[24m�[39m Arguments #self#�[36m::Core.Const(Main.var\"workspace#4\".double)�[39m mapping�[36m::Dict{Symbol, AbstractFloat}�[39m key�[36m::Symbol�[39m Body�[91m�[1m::Any�[22m�[39m �[90m1 ─�[39m %1 = Base.getindex(mapping, key)�[91m�[1m::AbstractFloat�[22m�[39m �[90m│ �[39m %2 = (2 * %1)�[91m�[1m::Any�[22m�[39m �[90m└──�[39m return %2
We can fix this by forcing all elements in the dictionary to have the same type. Specifically, to we force all elements to be of type Float64
:
typednumbers = Dict{Symbol, Float64}(:one => 1f0, :two => 2.0)
Dict{Symbol, Float64} with 2 entries: :two => 2.0 :one => 1.0
This gets rid of all the type warnings:
with_terminal() do
@code_warntype double(typednumbers, :one)
end
MethodInstance for Main.var\"workspace#4\".double(::Dict{Symbol, Float64}, ::Symbol) from double(�[90mmapping�[39m, �[90mkey�[39m::�[1mSymbol�[22m)�[90m @�[39m �[90mMain.var\"workspace#4\"�[39m �[90m~/work/JuliaTutorialsTemplate/JuliaTutorialsTemplate/tutorials/�[39m�[90m�[4mbenchmarking.jl#==#3f0e2049-8597-4dac-b499-4d7a8a35978e:1�[24m�[39m Arguments #self#�[36m::Core.Const(Main.var\"workspace#4\".double)�[39m mapping�[36m::Dict{Symbol, Float64}�[39m key�[36m::Symbol�[39m Body�[36m::Float64�[39m �[90m1 ─�[39m %1 = Base.getindex(mapping, key)�[36m::Float64�[39m �[90m│ �[39m %2 = (2 * %1)�[36m::Float64�[39m �[90m└──�[39m return %2
And makes the method more quick:
using BenchmarkTools
with_benchmark_terminal() do
@benchmark double(numbers, :one)
end
BenchmarkTools.Trial: 10000 samples with 990 evaluations. Range (min … max): 40.303 ns … 3.804 μs ┊ GC (min … max): 0.00% … 97.73% Time (median): 50.910 ns ┊ GC (median): 0.00% Time (mean ± σ): 58.816 ns ± 58.810 ns ┊ GC (mean ± σ): 1.21% ± 1.38% ▃▇█▅ ▂▃████▇██▇▄▅▄▄▄▄▃▃▃▃▃▂▃▃▃▃▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▁▂▂▂▂▂ ▃ 40.3 ns Histogram: frequency by time 141 ns < Memory estimate: 16 bytes, allocs estimate: 1.
with_benchmark_terminal() do
@benchmark double(typednumbers, :one)
end
BenchmarkTools.Trial: 10000 samples with 996 evaluations. Range (min … max): 22.289 ns … 21.118 μs ┊ GC (min … max): 0.00% … 0.00% Time (median): 27.108 ns ┊ GC (median): 0.00% Time (mean ± σ): 70.159 ns ± 670.966 ns ┊ GC (mean ± σ): 4.03% ± 1.71% ▅▇█▅▅▄▃▅▆▅▃▃▃▃▃▃▂▁▁▁▁▁ ▂ ████████████████████████▇▇▇██▇▇▇▇▇▇▇▆▅▅▅▅▅▃▅▅▃▅▄▃▄▄▂▄▃▃▂▄▄▅▄ █ 22.3 ns Histogram: log(frequency) by time 104 ns < Memory estimate: 16 bytes, allocs estimate: 1.
Appendix
function with_benchmark_terminal(f)
out = sprint(show, "text/plain", f())
with_terminal() do
print(out)
end
end;
Built with Julia 1.9.1 and
BenchmarkTools 1.3.2PlutoUI 0.7.51
To run this tutorial locally, download this file and open it with Pluto.jl.