Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plot numeric-keyed groups #324

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions BenchmarkPlots/src/BenchmarkPlots.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module BenchmarkPlots
using RecipesBase
using BenchmarkTools: Trial, BenchmarkGroup
using BenchmarkTools: Trial, BenchmarkGroup, mean

@recipe function f(::Type{Trial}, t::Trial)
seriestype --> :violin
Expand All @@ -10,16 +10,31 @@ using BenchmarkTools: Trial, BenchmarkGroup
t.times
end

@recipe function f(g::BenchmarkGroup, keys=keys(g))
legend --> false
@recipe function f(g::BenchmarkGroup, keyset=keys(g))
yguide --> "t / ns"
for k in keys
@series begin
label --> string(k)
xticks --> true
[string(k)], g[k]
if all(isa.(keyset, Number))
keyvec = sort([keyset...])
fillrange := [mean(g[key]).time for key in keyvec]
seriestype --> :path
fillalpha --> 0.5
keyvec, [minimum(g[key]).time for key in keyvec]
else
legend --> false
for key in keyset
@series begin
label --> string(key)
xticks --> true
[string(key)], g[key]
end
end
end
end

# If a BenchmarkGroup has BenchmarkGroups for elements, ignore the xtick string given by
# parent, just run BenchmarkGroup recipe again
@recipe function f(::AbstractVector{String}, g::BenchmarkGroup)
legend --> true
return g
end

end
28 changes: 28 additions & 0 deletions docs/generate_plots.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using BenchmarkTools, Plots, BenchmarkPlots, StatsPlots

function runalgorithm(x, alg)
alg == :default && return sort(x)
alg == :insertion && return sort(x; alg=InsertionSort)
alg == :quick && return sort(x; alg=QuickSort)
alg == :merge && return sort(x; alg=MergeSort)
end

g = BenchmarkGroup()
for key in [:default, :insertion, :quick, :merge]
g[key] = @benchmarkable runalgorithm(x, $key) setup=(x=randn(1000))
end
res = run(g)
plot(res; yscale=:log10)
savefig("$(pkgdir(BenchmarkTools))/docs/src/assets/violins.png")

g = BenchmarkGroup()
for key in [:default, :insertion, :quick, :merge]
g[key] = BenchmarkGroup()
for size in 2 .^ (1:15)
g[key][size] = @benchmarkable runalgorithm(x, $key) setup=(x=randn($size))
end
end
res = run(g)
plot(res; scale=:log10, xguide=:size, legendposition=:topleft)
savefig("$(pkgdir(BenchmarkTools))/docs/src/assets/algorithms.png")

Binary file added docs/src/assets/algorithms.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/src/assets/violins.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 37 additions & 4 deletions docs/src/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -974,19 +974,52 @@ plot(t)
```

This will show the timing results of the trial as a violin plot. You can use
all the keyword arguments from `Plots.jl`, for instance `st=:box` or
`yaxis=:log10`.
all the keyword arguments from `Plots.jl`, for instance `seriestype=:box` or
`yscale=:log10`.

If a `BenchmarkGroup` contains (only) `Trial`s, its results can be visualized
simply by

```julia
using BenchmarkPlots, StatsPlots
g = BenchmarkGroup()
for alg in algorithm_symbols
g[alg] = @benchmarkable runalgorithm(x, $alg) setup=(x=randn(1000))
end
t = run(g)
plot(t)
plot(t; yscale=:log10)
```

This will display each `Trial` as a violin plot.

![Violin plots of BenchmarkGroup](./assets/violins.png)

A `BenchmarkGroup` whose
elements are `BenchmarkGroup`s can be visualized the same way, but no separation
will be made between the element groups - shared keys will get several violins,
and there is no visual indication that a result belongs to one group or the
other.

The exception is `BenchmarkGroup`s whose keys are `Number`s. These keys will be
interpreted as a size parameter, and the violin plots will be replaced by a line
plot showing the minimum time, with a shaded region up to the mean time. If you
want to bypass this, to still get violin (or similar) plots for the numeric
keys, explicitly make them strings.

```julia
g = BenchmarkGroup()
for alg in algorithm_symbols
g[alg] = BenchmarkGroup()
for size in 2 .^ [1:15]
g[alg][size] = @benchmarkable runalgorithm(x, $alg)
setup=(x=randn($size))
end
end
t = run(g)
plot(t; scale=:log10, xguide="size", legendposition=:topleft)
```

This will display each `Trial` as a violin plot.
![Plot of a BenchmarkGroup containing BenchmarkGroups with numerical keys](./assets/algorithms.png)

## Miscellaneous tips and info

Expand Down