← Back to index

lib/BDD/Behave/Benchmark.rakumod

36 / 36 lines covered (100.0%)

1unit module BDD::Behave::Benchmark;23our class BenchmarkResult {4  has Str  $.label;5  has Int  $.position;6  has Int  $.iterations is required;7  has      @.timings    is required;8  has Real $.min;9  has Real $.max;10  has Real $.mean;11  has Real $.median;12  has Real $.total;1314  submethod TWEAK {15    return unless @!timings.elems;16    my @sorted = @!timings.sort;17    $!min   = @sorted[0];18    $!max   = @sorted[*-1];19    $!total = [+] @!timings;20    $!mean  = $!total / @!timings.elems;21    my $n   = @sorted.elems;22    $!median = $n %% 223      ?? (@sorted[$n div 2 - 1] + @sorted[$n div 2]) / 224      !! @sorted[$n div 2];25  }2627  method key(--> Str) {28    $!label.defined ?? "label:$!label" !! "pos:" ~ ($!position // 0);29  }30}3132sub attach-to-current-example(BenchmarkResult $result --> Nil) {33  my $current;34  try { $current = $*BEHAVE-CURRENT-EXAMPLE if $*BEHAVE-CURRENT-EXAMPLE.defined }35  return unless $current.defined;36  $current.benchmarks.push: $result;37}3839sub next-position(--> Int) {40  my $pos = 0;41  try {42    if $*BEHAVE-BENCHMARK-COUNTER.defined {43      $pos = $*BEHAVE-BENCHMARK-COUNTER;44      $*BEHAVE-BENCHMARK-COUNTER++;45    }46  }47  $pos;48}4950sub run-iterations(&block, Int $iterations, Int $warmup, $label --> BenchmarkResult) {51  die "benchmark iterations must be a positive integer (got: $iterations)"52    unless $iterations > 0;53  die "benchmark warmup must be 0 or a positive integer (got: $warmup)"54    if $warmup < 0;5556  my $position = next-position();5758  for ^$warmup { block() }5960  my @timings;61  for ^$iterations {62    my $start = now;63    block();64    my $finish = now;65    @timings.push: ($finish - $start).Real;66  }6768  my $result = BenchmarkResult.new(69    :label($label // Str),70    :$position,71    :$iterations,72    :@timings,73  );74  attach-to-current-example($result);75  $result;76}7778our proto sub benchmark(|) is export {*}7980our multi sub benchmark(&block, Int :$iterations = 100, Int :$warmup = 0, Str :$label) is export {81  run-iterations(&block, $iterations, $warmup, $label);82}8384our multi sub benchmark(Str:D $label, &block, Int :$iterations = 100, Int :$warmup = 0) is export {85  run-iterations(&block, $iterations, $warmup, $label);86}