forked from ponylang/ponyc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New Ponybench API (RFC 52) (ponylang#2578)
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
Showing
12 changed files
with
678 additions
and
356 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.