time: add Timer; refactor benchmark to use Timer

pull/4509/head
Major Taylor 2020-04-18 21:40:32 -04:00 committed by GitHub
parent 57c142b993
commit be0a8794c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 26 deletions

View File

@ -54,10 +54,8 @@ const (
pub struct Benchmark { pub struct Benchmark {
pub mut: pub mut:
bench_start_time i64 bench_timer time.Timer
bench_end_time i64 step_timer time.Timer
step_start_time i64
step_end_time i64
ntotal int ntotal int
nok int nok int
nfail int nfail int
@ -72,14 +70,14 @@ pub mut:
pub fn new_benchmark() Benchmark { pub fn new_benchmark() Benchmark {
return Benchmark{ return Benchmark{
bench_start_time: benchmark.now() bench_timer: time.new_timer()
verbose: true verbose: true
} }
} }
pub fn new_benchmark_no_cstep() Benchmark { pub fn new_benchmark_no_cstep() Benchmark {
return Benchmark{ return Benchmark{
bench_start_time: benchmark.now() bench_timer: time.new_timer()
verbose: true verbose: true
no_cstep: true no_cstep: true
} }
@ -87,7 +85,7 @@ pub fn new_benchmark_no_cstep() Benchmark {
pub fn new_benchmark_pointer() &Benchmark { pub fn new_benchmark_pointer() &Benchmark {
return &Benchmark{ return &Benchmark{
bench_start_time: benchmark.now() bench_timer: time.new_timer()
verbose: true verbose: true
} }
} }
@ -97,48 +95,48 @@ pub fn (b mut Benchmark) set_total_expected_steps(n int) {
} }
pub fn (b mut Benchmark) stop() { pub fn (b mut Benchmark) stop() {
b.bench_end_time = benchmark.now() b.bench_timer.stop()
} }
pub fn (b mut Benchmark) step() { pub fn (b mut Benchmark) step() {
b.step_start_time = benchmark.now() b.step_timer.restart()
if !b.no_cstep { if !b.no_cstep {
b.cstep++ b.cstep++
} }
} }
pub fn (b mut Benchmark) fail() { pub fn (b mut Benchmark) fail() {
b.step_end_time = benchmark.now() b.step_timer.stop()
b.ntotal++ b.ntotal++
b.nfail++ b.nfail++
} }
pub fn (b mut Benchmark) ok() { pub fn (b mut Benchmark) ok() {
b.step_end_time = benchmark.now() b.step_timer.stop()
b.ntotal++ b.ntotal++
b.nok++ b.nok++
} }
pub fn (b mut Benchmark) skip() { pub fn (b mut Benchmark) skip() {
b.step_end_time = benchmark.now() b.step_timer.stop()
b.ntotal++ b.ntotal++
b.nskip++ b.nskip++
} }
pub fn (b mut Benchmark) fail_many(n int) { pub fn (b mut Benchmark) fail_many(n int) {
b.step_end_time = benchmark.now() b.step_timer.stop()
b.ntotal += n b.ntotal += n
b.nfail += n b.nfail += n
} }
pub fn (b mut Benchmark) ok_many(n int) { pub fn (b mut Benchmark) ok_many(n int) {
b.step_end_time = benchmark.now() b.step_timer.stop()
b.ntotal += n b.ntotal += n
b.nok += n b.nok += n
} }
pub fn (b mut Benchmark) neither_fail_nor_ok() { pub fn (b mut Benchmark) neither_fail_nor_ok() {
b.step_end_time = benchmark.now() b.step_timer.stop()
} }
pub fn start() Benchmark { pub fn start() Benchmark {
@ -149,7 +147,7 @@ pub fn start() Benchmark {
pub fn (b mut Benchmark) measure(label string) i64 { pub fn (b mut Benchmark) measure(label string) i64 {
b.ok() b.ok()
res := b.step_end_time - b.step_start_time res := b.step_timer.elapsed()
println(b.step_message_with_label(BSPENT, 'in $label')) println(b.step_message_with_label(BSPENT, 'in $label'))
b.step() b.step()
return res return res
@ -174,10 +172,10 @@ pub fn (b &Benchmark) step_message_with_label(label string, msg string) string {
'${b.cstep:3d}/${b.nexpected_steps:3d}' '${b.cstep:3d}/${b.nexpected_steps:3d}'
} }
} }
timed_line = b.tdiff_in_ms('[${sprogress}] $msg', b.step_start_time, b.step_end_time) timed_line = b.tdiff_in_ms('[${sprogress}] $msg', b.step_timer.elapsed())
} }
else { else {
timed_line = b.tdiff_in_ms(msg, b.step_start_time, b.step_end_time) timed_line = b.tdiff_in_ms(msg, b.step_timer.elapsed())
} }
return '${label:-5s}${timed_line}' return '${label:-5s}${timed_line}'
} }
@ -203,22 +201,17 @@ pub fn (b &Benchmark) total_message(msg string) string {
if b.verbose { if b.verbose {
tmsg = '<=== total time spent $tmsg' tmsg = '<=== total time spent $tmsg'
} }
return ' ' + b.tdiff_in_ms(tmsg, b.bench_start_time, b.bench_end_time) return ' ' + b.tdiff_in_ms(tmsg, b.bench_timer.elapsed())
} }
pub fn (b &Benchmark) total_duration() i64 { pub fn (b &Benchmark) total_duration() i64 {
return (b.bench_end_time - b.bench_start_time) return b.bench_timer.elapsed()
} }
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
fn (b &Benchmark) tdiff_in_ms(s string, sticks i64, eticks i64) string { fn (b &Benchmark) tdiff_in_ms(s string, tdiff i64) string {
if b.verbose { if b.verbose {
tdiff := (eticks - sticks)
return '${tdiff:6d} ms $s' return '${tdiff:6d} ms $s'
} }
return s return s
} }
fn now() i64 {
return time.ticks()
}

60
vlib/time/timer.v 100644
View File

@ -0,0 +1,60 @@
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
module time
// Timer struct and functions
// start and end are # of ms since start of system.
// When end_ticks == 0, this means the timer is actively "running"
pub struct Timer {
pause_start i64
pub:
start_ticks i64
end_ticks i64
}
// start Starts the timer. If the timer was paused, restarts counting.
pub fn (t mut Timer) start() {
if t.pause_start == 0 {
t.start_ticks = ticks()
} else {
// We were paused, so pretend like the time we were paused didn't
// happen
t.start_ticks += ticks() - t.pause_start
}
t.end_ticks = 0
t.pause_start = 0
}
pub fn (t mut Timer) restart() {
t.end_ticks = 0
t.pause_start = 0
t.start_ticks = ticks()
}
pub fn (t mut Timer) pause() {
t.pause_start = ticks()
t.end_ticks = t.pause_start // so elapsed() still keeps track of the cared-amount of time
}
pub fn (t mut Timer) stop() {
t.end_ticks = ticks()
t.pause_start = 0
}
// elapsed If the Timer is stopped, returns the number of milliseconds between
// the last start and stop.
// If the Timer is still running, returns the number of milliseconds from the
// last start to now.
pub fn (t Timer) elapsed() i64 {
if t.end_ticks == 0 {
return ticks() - t.start_ticks
} else {
return t.end_ticks - t.start_ticks
}
}
pub fn new_timer() Timer {
return Timer{start_ticks: ticks()}
}