Skip to content

Commit

Permalink
New Ponybench API (RFC 52) (ponylang#2578)
Browse files Browse the repository at this point in the history
This PR implements most of RFC 52 with a new Ponybench API, documentation,
and example program. More examples using data visualization in the tutorial
are still needed.
  • Loading branch information
Theodus authored and dipinhora committed Jun 5, 2018
1 parent c45e99e commit e57154e
Show file tree
Hide file tree
Showing 12 changed files with 678 additions and 356 deletions.
62 changes: 62 additions & 0 deletions examples/ponybench/main.pony
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use "ponybench"
use "time"

actor Main is BenchmarkList
new create(env: Env) =>
PonyBench(env, this)

fun tag benchmarks(bench: PonyBench) =>
bench(_Nothing)
bench(_Fib(5))
bench(_Fib(10))
bench(_Fib(20))
bench(_Timer(10_000))

class iso _Nothing is MicroBenchmark
// Benchmark absolutely nothing.
fun name(): String => "Nothing"

fun apply() =>
// prevent compiler from optimizing out this operation
DoNotOptimise[None](None)
DoNotOptimise.observe()

class iso _Fib is MicroBenchmark
// Benchmark non-tail-recursive fibonacci
let _n: U64

new iso create(n: U64) =>
_n = n

fun name(): String =>
"_Fib(" + _n.string() + ")"

fun apply() =>
DoNotOptimise[U64](_fib(_n))
DoNotOptimise.observe()

fun _fib(n: U64): U64 =>
if n < 2 then 1
else _fib(n - 1) + _fib(n - 2)
end

class iso _Timer is AsyncMicroBenchmark
// Asynchronous benchmark of timer.
let _ts: Timers = Timers
let _ns: U64

new iso create(ns: U64) =>
_ns = ns

fun name(): String =>
"_Timer (" + _ns.string() + " ns)"

fun apply(c: AsyncBenchContinue) =>
_ts(Timer(
object iso is TimerNotify
fun apply(timer: Timer, count: U64 = 0): Bool =>
// signal completion of async benchmark iteration when timer fires
c.complete()
false
end,
_ns))
81 changes: 81 additions & 0 deletions packages/ponybench/_aggregator.pony
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@

class ref _Aggregator
let _ponybench: PonyBench
let _runner: _Runner
let _overhead: Bool
let _config: BenchConfig
var _samples: Array[U64] iso
var _warmup: Bool = true
var iterations: U64 = 1

new create(
ponybench: PonyBench,
runner: _Runner,
config: BenchConfig,
overhead: Bool)
=>
_ponybench = ponybench
_runner = runner
_overhead = overhead
_config = config
_samples = recover Array[U64](_config.samples) end

fun ref complete(name: String, t: U64) =>
if _warmup then
match _calc_iterations(t)
| let n: U64 => iterations = n
| None => _warmup = false
end
_runner()
else
_samples.push(t)
if _samples.size() < _config.samples then
_runner()
else
_ponybench._complete(_Results(
name,
_samples = recover [] end,
iterations,
_overhead))
end
end

fun ref _calc_iterations(runtime: U64): (U64 | None) =>
let max_i = _config.max_iterations
let max_t = _config.max_sample_time
let nspi = runtime / iterations
if (runtime < max_t) and (iterations < max_i) then
var itrs' =
if nspi == 0 then max_i
else max_t / nspi
end
itrs' = (itrs' + (itrs' / 5)).min(iterations * 100).max(iterations + 1)
_round_up(itrs')
else
iterations = iterations.min(max_i)
None
end

fun _round_up(x: U64): U64 =>
"""
Round x up to a number of the form [1^x, 2^x, 3^x, 5^x].
"""
let base = _round_down_10(x)
if x <= base then
base
elseif x <= (base * 2) then
base * 2
elseif x <= (base * 3) then
base * 3
elseif x <= (base * 5) then
base * 5
else
base * 10
end

fun _round_down_10(x: U64): U64 =>
"""
Round down to the nearest power of 10.
"""
let tens = x.f64().log10().floor()
F64(10).pow(tens).u64()
126 changes: 0 additions & 126 deletions packages/ponybench/_auto_bench.pony

This file was deleted.

24 changes: 0 additions & 24 deletions packages/ponybench/_bench.pony

This file was deleted.

55 changes: 0 additions & 55 deletions packages/ponybench/_bench_async.pony

This file was deleted.

Loading

0 comments on commit e57154e

Please sign in to comment.