Skip to content

Commit 454ffb8

Browse files
committed
tuesday
1 parent 53537f6 commit 454ffb8

File tree

1 file changed

+85
-85
lines changed

1 file changed

+85
-85
lines changed

src/trials.jl

Lines changed: 85 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -346,93 +346,91 @@ Base.show(io::IO, t::TrialEstimate) = _show(io, t)
346346
Base.show(io::IO, t::TrialRatio) = _show(io, t)
347347
Base.show(io::IO, t::TrialJudgement) = _show(io, t)
348348

349-
_percentile() = 99 # to tweak this live, TODO remove
350-
351349
function Base.show(io::IO, ::MIME"text/plain", t::Trial)
352-
353350
pad = get(io, :pad, "")
354351
padcolor = :light_black
355352

356-
showpercentile = _percentile()
353+
showpercentile = 99 # used both for display time, and to set right cutoff of histogram
357354

358-
perm = sortperm(t.times)
359-
times = t.times[perm]
360-
gctimes = t.gctimes[perm]
355+
allocsstr = if allocs(t) == 0
356+
"0 allocations"
357+
elseif allocs(t) == 1
358+
"1 allocation, " * prettymemory(memory(t))
359+
else
360+
prettycount(allocs(t)) * " allocations, total " * prettymemory(memory(t))
361+
end
362+
363+
samplesstr = string(
364+
prettycount(length(t)),
365+
if length(t) == 1 " sample, with " else " samples, each " end,
366+
prettycount(t.params.evals),
367+
if t.params.evals == 1 " evaluation" else " evaluations" end,
368+
)
361369

362370
if length(t) == 0
363371
print(io, "BenchmarkTools.Trial: 0 samples")
364372
return
365373
elseif length(t) == 1
366-
println(io, "BenchmarkTools.Trial:")
374+
printstyled(io, "BenchmarkTools.Trial:\n"; color=padcolor)
367375
# Time
368-
print(io, pad, "│ Only 1 sample: ")
369-
printstyled(io, prettytime(times[1]); color=:green)
376+
printstyled(io, pad, ""; color=padcolor)
377+
print(io, "time ")
378+
printstyled(io, prettytime(t.times[1]); color=:green, bold=true)
370379

371380
# Memory
372381
println(io)
373-
print(io, pad, "", prettycount(t.allocs[1]), " allocation", t.allocs[1]==1 ? "" : "s")
374-
if t.allocs[1] > 0
375-
print(io, ", ", prettymemory(t.memory[1]))
376-
end
382+
printstyled(io, pad, ""; color=padcolor)
383+
print(io, allocsstr)
377384

378385
# GC time
379386
if t.gctimes[1] > 0
380387
println(io)
381-
print(io, pad, "│ GC time: ", prettytime(t.gctimes[1]))
388+
printstyled(io, pad, ""; color=padcolor)
389+
print(io, "GC time: ", prettytime(t.gctimes[1]))
382390
printstyled(io, " (", prettypercent(t.gctimes[1] / t.times[1]),")"; color=:green)
383391
end
384-
return
385-
end # done with trivial cases.
386-
387-
med = median(t)
388-
avg = mean(t)
389-
min = minimum(t)
390-
max = maximum(t)
391-
q99 = quantile(t, showpercentile/100)
392392

393-
mintime = prettytime(time(min))
394-
medtime = prettytime(time(med))
395-
avgtime = prettytime(time(avg))
396-
q99time = prettytime(time(q99))
397-
398-
# Mean GC time is just that; then we take the percentage of the mean time
399-
avggctime, avegcpercent = prettytime(mean(gctimes)), prettypercent(mean(gctimes) / mean(times))
400-
q99gctime = prettytime(quantile(gctimes, showpercentile/100))
401-
# Maximum GC time has a percentage which is of the same run, not necc. the longest run
402-
_t, _i = findmax(gctimes)
403-
maxgctime, maxgcpercent = prettytime(_t), prettypercent(_t / times[_i])
393+
#
394+
println(io)
395+
printstyled(io, pad, "", samplesstr; color=padcolor)
404396

405-
memorystr = prettymemory(memory(min))
406-
allocsstr = prettycount(allocs(min)) * (allocs(min)==1 ? " allocation" : " allocations")
397+
return
398+
end # done with trivial cases.
407399

408400
# Main text block:
409-
410401
printstyled(io, "BenchmarkTools.Trial:\n"; color=padcolor)
411402

412403
printstyled(io, pad, ""; color=padcolor)
413404
printstyled(io, "min "; color=:default)
414-
printstyled(io, mintime; color=:default, bold=true)
405+
printstyled(io, prettytime(minimum(t.times)); color=:default, bold=true)
415406
print(io, ", ")
416407
printstyled(io, "median "; color=:blue)
417-
printstyled(io, medtime; color=:blue, bold=true)
418-
printstyled(io, " (½)"; color=:blue)
408+
printstyled(io, prettytime(median(t.times)); color=:blue, bold=true)
409+
# printstyled(io, " (½)"; color=:blue)
419410
print(io, ", ")
420411
printstyled(io, "mean "; color=:green)
421-
printstyled(io, avgtime; color=:green, bold=true)
422-
printstyled(io, " (*)"; color=:green)
412+
printstyled(io, prettytime(mean(t.times)); color=:green, bold=true)
413+
# printstyled(io, " (*)"; color=:green)
423414
print(io, ", ")
424415
print(io, showpercentile, "ᵗʰ ")
425-
printstyled(q99time; bold=true)
416+
printstyled(prettytime(quantile(t.times, showpercentile/100)); bold=true)
426417
println(io)
427418

428419
printstyled(io, pad, ""; color=padcolor)
429-
print(io, allocsstr)
430-
if allocs(min) != 0
431-
println(io, ", ", memorystr)
432-
else
433-
println(io)
434-
end
435-
if !all(iszero, gctimes)
420+
println(io, allocsstr)
421+
422+
if !all(iszero, t.gctimes)
423+
# Mean GC time is just that; then we take the percentage of the mean time
424+
avggctime = prettytime(mean(t.gctimes))
425+
avegcpercent = prettypercent(mean(t.gctimes) / mean(t.times))
426+
427+
# Maximum GC time is not taken as the GC time of the slowst run, max(t).
428+
# The percentage shown is of the same max-GC run, again not the percentage of longest time.
429+
# Of course, very often the slowest run is due to GC, and these concerns won't matter.
430+
_t, _i = findmax(t.gctimes)
431+
maxgctime = prettytime(_t)
432+
maxgcpercent = prettypercent(_t / t.gctimes[_i])
433+
436434
printstyled(io, pad, ""; color=padcolor)
437435
print(io, "GC time: mean ", avggctime)
438436
printstyled(io, " (", avegcpercent, ")"; color=:green)
@@ -445,7 +443,11 @@ function Base.show(io::IO, ::MIME"text/plain", t::Trial)
445443
histquantile = showpercentile/100
446444
# The height and width of the printed histogram in characters:
447445
histheight = 2
448-
histwidth = 74 # fits into 78 chars, as does 1st line with 4 times
446+
histwidth = 78-4 # fits into 78 chars # TODO read this from io?
447+
448+
perm = sortperm(t.times)
449+
times = t.times[perm]
450+
gctimes = t.gctimes[perm]
449451

450452
# This needs sorted times:
451453
histtimes = times[1:round(Int, histquantile*end)]
@@ -454,8 +456,7 @@ function Base.show(io::IO, ::MIME"text/plain", t::Trial)
454456
logbins = get(io, :logbins, nothing)
455457
bins = bindata(histtimes, histwidth - 1, histmin, histmax)
456458
append!(bins, [1, floor((1-histquantile) * length(times))])
457-
# if median size of (bins with >10% average data/bin) is less than 5% of max bin size, log the bin sizes
458-
if logbins === true # || (logbins === nothing && median(filter(b -> b > 0.1 * length(times) / histwidth, bins)) / maximum(bins) < 0.05)
459+
if logbins === true
459460
bins, logbins = log.(1 .+ bins), true
460461
else
461462
logbins = false
@@ -468,19 +469,31 @@ function Base.show(io::IO, ::MIME"text/plain", t::Trial)
468469
if delta1 > 0
469470
medpos = 1 + round(Int, (histtimes[length(times) ÷ 2] - histmin) / delta1)
470471
avgpos = 1 + round(Int, (mean(times) - histmin) / delta1)
472+
# TODO replace with searchsortedfirst & range?
473+
q25pos = 1 + round(Int, (histtimes[max(1,length(times) ÷ 4)] - histmin) / delta1)
474+
q75pos = 1 + round(Int, (histtimes[3*length(times) ÷ 4] - histmin) / delta1)
471475
else
472476
medpos, avgpos = 1, 1
477+
q25pos, q75pos = 1, 1
473478
end
474479

475480
# Above the histogram bars, print markers for special ones:
476-
# println(io)
477481
printstyled(io, pad, ""; color=padcolor)
482+
istop = maximum(filter(i -> i in axes(hist,2), [avgpos, medpos+1, q75pos]))
478483
for i in axes(hist, 2)
484+
i > istop && break
479485
if i == avgpos
480-
printstyled(io, "*", color=:green, bold=true) # or μ, or t̄?
486+
printstyled(io, "*", color=:green, bold=true)
481487
elseif i == medpos || (medpos==avgpos && i==medpos-1)
482488
# marker for "median" is moved one to the left if they collide
483-
printstyled(io, "½", color=:blue) # sadly "㊿" is often double wide. ½, |, ‖, ↓ maybe?
489+
# printstyled(io, "½", color=:blue)
490+
printstyled(io, "", color=:blue)
491+
elseif i == q25pos
492+
# printstyled(io, "¼", color=:light_black)
493+
printstyled(io, "", color=:light_black)
494+
elseif i == q75pos
495+
# printstyled(io, "¾", color=:light_black)
496+
printstyled(io, "", color=:light_black)
484497
else
485498
print(io, " ")
486499
end
@@ -489,7 +502,9 @@ function Base.show(io::IO, ::MIME"text/plain", t::Trial)
489502
for r in axes(hist, 1)
490503
println(io)
491504
printstyled(io, pad, ""; color=padcolor)
505+
istop = findlast(!=(' '), view(hist, r, :))
492506
for (i, bar) in enumerate(view(hist, r, :))
507+
i > istop && break # don't print trailing spaces, as they waste space when line-wrapped
493508
color = :default
494509
if i == avgpos
495510
color = :green
@@ -509,43 +524,28 @@ function Base.show(io::IO, ::MIME"text/plain", t::Trial)
509524
printstyled(io, pad, ""; color=padcolor)
510525
print(io, minhisttime)
511526
# Caption is only printed if logbins has been selected:
512-
caption = string(prettycount(length(t)), " sample", if length(t) > 1 "s" else "" end,
513-
", each ", prettycount(t.params.evals), " evaluation", if t.params.evals > 1 "s" else "" end)
514-
caption = logbins ? ("log(counts) from " * caption) : caption
527+
caption = logbins ? ("log(counts) from " * samplesstr) : samplesstr
515528
printstyled(io, " " ^ ((histwidth - length(caption)) ÷ 2 - length(minhisttime)), caption; color=:light_black)
516529
print(io, lpad(maxhisttime, ceil(Int, (histwidth - length(caption)) / 2) - 1), " ")
517530
print(io, "+")
531+
# printstyled(io, "●", color=:light_black) # other options...
532+
# print(io, "⋯")
533+
# printstyled(io, "¹⁰⁰", color=:light_black)
518534
end
519535

520-
# These two functions allow endpoints 6, 7, 8, 10, 15, 20, 30, 40, ... perhaps too coarse?
521-
# exp.(range(log(1), log(10), length=11)) ≈ [1, 1.25, 1.6, 2, 2.5, 3.2, 4, 5, 6.3, 8, 10]
522-
523-
# round.(0:0.01:10, sigdigits=3, base=2) |> unique # looks good in 1:10, not great outside
536+
# I wondered about rounding to a few steps per decade. This looks good in 1:10, not great outside:
537+
# round.(0:0.01:10, sigdigits=3, base=2) |> unique
524538
function low_edge(times)
525-
# return 0
526-
min = minimum(times)
527-
# return round(min, RoundDown; sigdigits = 3, base = 2)
528-
return round(min, RoundDown; sigdigits = 2)
529-
# dec = round(min, RoundDown; sigdigits = 1)
530-
# if first(string(dec)) == '1'
531-
# min > 1.5 * dec && return 1.5 * dec
532-
# # min > 1.2 * dec && return 1.2 * dec
533-
# elseif first(string(dec)) == '9'
534-
# return round((8//9) * dec, sigdigits = 2)
535-
# end
536-
# dec
539+
# _min = minimum(times)
540+
_min = min(minimum(times), mean(times) / 1.03) # demand low edge 3% below mean
541+
return round(_min, RoundDown; sigdigits = 2)
542+
537543
end
538544
function high_edge(times)
539-
max = maximum(times)
540-
# return round(max, RoundUp; sigdigits = 3, base = 2)
541-
return round(max, RoundUp; sigdigits = 2)
542-
# dec = round(max, RoundUp; sigdigits = 1)
543-
# if first(string(dec)) == '2'
544-
# max < 0.75 * dec && return 0.75 * dec
545-
# elseif first(string(dec)) == '9'
546-
# return round((10//9) * dec, sigdigits = 2)
547-
# end
548-
# dec
545+
# _max = maximum(times)
546+
# _max = Base.max(maximum(times), 1.07 * low_edge(times)) # demand total width at least 7%
547+
_max = max(maximum(times), 1.03 * mean(times)) # demand high edge 3% above mean
548+
return round(_max, RoundUp; sigdigits = 2)
549549
end
550550

551551
function Base.show(io::IO, ::MIME"text/plain", t::TrialEstimate)

0 commit comments

Comments
 (0)