mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
time: Timer -> StopWatch; time.Duration
This commit is contained in:
parent
f3e3d7e0c5
commit
25f2b171fc
@ -54,8 +54,8 @@ const (
|
||||
|
||||
pub struct Benchmark {
|
||||
pub mut:
|
||||
bench_timer time.Timer
|
||||
step_timer time.Timer
|
||||
bench_timer time.StopWatch
|
||||
step_timer time.StopWatch
|
||||
ntotal int
|
||||
nok int
|
||||
nfail int
|
||||
@ -70,14 +70,14 @@ pub mut:
|
||||
|
||||
pub fn new_benchmark() Benchmark {
|
||||
return Benchmark{
|
||||
bench_timer: time.new_timer()
|
||||
bench_timer: time.new_stopwatch()
|
||||
verbose: true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_benchmark_no_cstep() Benchmark {
|
||||
return Benchmark{
|
||||
bench_timer: time.new_timer()
|
||||
bench_timer: time.new_stopwatch()
|
||||
verbose: true
|
||||
no_cstep: true
|
||||
}
|
||||
@ -85,7 +85,7 @@ pub fn new_benchmark_no_cstep() Benchmark {
|
||||
|
||||
pub fn new_benchmark_pointer() &Benchmark {
|
||||
return &Benchmark{
|
||||
bench_timer: time.new_timer()
|
||||
bench_timer: time.new_stopwatch()
|
||||
verbose: true
|
||||
}
|
||||
}
|
||||
@ -147,7 +147,7 @@ pub fn start() Benchmark {
|
||||
|
||||
pub fn (b mut Benchmark) measure(label string) i64 {
|
||||
b.ok()
|
||||
res := b.step_timer.elapsed()
|
||||
res := b.step_timer.elapsed().milliseconds()
|
||||
println(b.step_message_with_label(BSPENT, 'in $label'))
|
||||
b.step()
|
||||
return res
|
||||
@ -172,10 +172,10 @@ pub fn (b &Benchmark) step_message_with_label(label string, msg string) string {
|
||||
'${b.cstep:3d}/${b.nexpected_steps:3d}'
|
||||
}
|
||||
}
|
||||
timed_line = b.tdiff_in_ms('[${sprogress}] $msg', b.step_timer.elapsed())
|
||||
timed_line = b.tdiff_in_ms('[${sprogress}] $msg', b.step_timer.elapsed().milliseconds())
|
||||
}
|
||||
else {
|
||||
timed_line = b.tdiff_in_ms(msg, b.step_timer.elapsed())
|
||||
timed_line = b.tdiff_in_ms(msg, b.step_timer.elapsed().milliseconds())
|
||||
}
|
||||
return '${label:-5s}${timed_line}'
|
||||
}
|
||||
@ -201,11 +201,11 @@ pub fn (b &Benchmark) total_message(msg string) string {
|
||||
if b.verbose {
|
||||
tmsg = '<=== total time spent $tmsg'
|
||||
}
|
||||
return ' ' + b.tdiff_in_ms(tmsg, b.bench_timer.elapsed())
|
||||
return ' ' + b.tdiff_in_ms(tmsg, b.bench_timer.elapsed().milliseconds())
|
||||
}
|
||||
|
||||
pub fn (b &Benchmark) total_duration() i64 {
|
||||
return b.bench_timer.elapsed()
|
||||
return b.bench_timer.elapsed().milliseconds()
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////
|
||||
|
52
vlib/time/stopwatch.v
Normal file
52
vlib/time/stopwatch.v
Normal file
@ -0,0 +1,52 @@
|
||||
// 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
|
||||
|
||||
pub struct StopWatch {
|
||||
pause_time u64
|
||||
pub:
|
||||
start u64
|
||||
end u64
|
||||
}
|
||||
|
||||
pub fn new_stopwatch() StopWatch {
|
||||
return StopWatch{start: time.sys_mono_now()}
|
||||
}
|
||||
|
||||
// start Starts the timer. If the timer was paused, restarts counting.
|
||||
pub fn (t mut StopWatch) start() {
|
||||
if t.pause_time == 0 {
|
||||
t.start = time.sys_mono_now()
|
||||
} else {
|
||||
t.start += time.sys_mono_now() - t.pause_time
|
||||
}
|
||||
t.end = 0
|
||||
t.pause_time = 0
|
||||
}
|
||||
|
||||
pub fn (t mut StopWatch) restart() {
|
||||
t.end = 0
|
||||
t.pause_time = 0
|
||||
t.start = time.sys_mono_now()
|
||||
}
|
||||
|
||||
pub fn (t mut StopWatch) stop() {
|
||||
t.end = time.sys_mono_now()
|
||||
t.pause_time = 0
|
||||
}
|
||||
|
||||
pub fn (t mut StopWatch) pause() {
|
||||
t.pause_time = time.sys_mono_now()
|
||||
t.end = t.pause_time // so elapsed keeps track of actual running time
|
||||
}
|
||||
|
||||
// elapsed returns the Duration since the last start call
|
||||
pub fn (t StopWatch) elapsed() Duration {
|
||||
if t.end == 0 {
|
||||
return Duration(time.sys_mono_now() - t.start)
|
||||
} else {
|
||||
return Duration(t.end - t.start)
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,21 @@ const (
|
||||
days_per_400_years = 365 * 400 + 97
|
||||
days_per_100_years = 365 * 100 + 24
|
||||
days_per_4_years = 365 * 4 + 1
|
||||
days_before = [0, 31, 31 + 28, 31 + 28 + 31, 31 + 28 + 31 + 30, 31 + 28 + 31 + 30 + 31, 31 + 28 + 31 + 30 + 31 + 30, 31 + 28 + 31 + 30 + 31 + 30 + 31, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31, ]
|
||||
days_before = [
|
||||
0,
|
||||
31,
|
||||
31 + 28,
|
||||
31 + 28 + 31,
|
||||
31 + 28 + 31 + 30,
|
||||
31 + 28 + 31 + 30 + 31,
|
||||
31 + 28 + 31 + 30 + 31 + 30,
|
||||
31 + 28 + 31 + 30 + 31 + 30 + 31,
|
||||
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
|
||||
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
|
||||
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
|
||||
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
|
||||
31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31,
|
||||
]
|
||||
)
|
||||
|
||||
pub struct Time {
|
||||
@ -121,7 +135,7 @@ pub fn (t Time) unix_time() int {
|
||||
return make_unix_time(tt)
|
||||
}
|
||||
|
||||
// add_days returns a new time struct with an added number of seconds.
|
||||
// add_seconds returns a new time struct with an added number of seconds.
|
||||
pub fn (t Time) add_seconds(seconds int) Time {
|
||||
// TODO Add(d time.Duration)
|
||||
return unix(t.unix + seconds)
|
||||
@ -265,3 +279,48 @@ fn convert_ctime(t C.tm) Time {
|
||||
unix: make_unix_time(t)
|
||||
}
|
||||
}
|
||||
|
||||
// A lot of these are taken from the Go library
|
||||
pub type Duration i64
|
||||
|
||||
pub const(
|
||||
nanosecond = Duration(1)
|
||||
microsecond = Duration(1000) * nanosecond
|
||||
millisecond = Duration(1000) * microsecond
|
||||
second = Duration(1000) * millisecond
|
||||
minute = Duration(60) * second
|
||||
hour = Duration(60) * minute
|
||||
)
|
||||
|
||||
// nanoseconds returns the duration as an integer number of nanoseconds.
|
||||
pub fn (d Duration) nanoseconds() i64 { return i64(d) }
|
||||
|
||||
// microseconds returns the duration as an integer number of microseconds.
|
||||
pub fn (d Duration) microseconds() i64 { return i64(d) / 1000 }
|
||||
|
||||
// milliseconds returns the duration as an integer number of milliseconds.
|
||||
pub fn (d Duration) milliseconds() i64 { return i64(d) / 1_000_000 }
|
||||
|
||||
// The following functions return floating point numbers because it's common to
|
||||
// consider all of them in sub-one intervals
|
||||
|
||||
// seconds returns the duration as a floating point number of seconds.
|
||||
pub fn (d Duration) seconds() f64 {
|
||||
sec := d / second
|
||||
nsec := d % second
|
||||
return f64(sec) + f64(nsec)/1e9
|
||||
}
|
||||
|
||||
// minutes returns the duration as a floating point number of minutes.
|
||||
pub fn (d Duration) minutes() f64 {
|
||||
min := d / minute
|
||||
nsec := d % minute
|
||||
return f64(min) + f64(nsec)/(60*1e9)
|
||||
}
|
||||
|
||||
// hours returns the duration as a floating point number of hours.
|
||||
pub fn (d Duration) hours() f64 {
|
||||
hr := d / hour
|
||||
nsec := d % hour
|
||||
return f64(hr) + f64(nsec)/(60*60*1e9)
|
||||
}
|
||||
|
40
vlib/time/time_darwin.c.v
Normal file
40
vlib/time/time_darwin.c.v
Normal file
@ -0,0 +1,40 @@
|
||||
module time
|
||||
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
const (
|
||||
// start_time is needed on Darwin and Windows because of potential overflows
|
||||
start_time = C.mach_absolute_time()
|
||||
time_base = init_time_base()
|
||||
)
|
||||
|
||||
[typedef]
|
||||
struct C.mach_timebase_info_data_t {
|
||||
numer u64
|
||||
denom u64
|
||||
}
|
||||
|
||||
fn C.mach_absolute_time() u64
|
||||
fn C.mach_timebase_info(&C.mach_timebase_info_data_t)
|
||||
|
||||
struct InternalTimeBase {
|
||||
numer u64
|
||||
denom u64
|
||||
}
|
||||
|
||||
fn init_time_base() InternalTimeBase {
|
||||
mut tb := C.mach_timebase_info_data_t{}
|
||||
C.mach_timebase_info(&tb)
|
||||
return InternalTimeBase{numer:tb.numer, denom:tb.denom}
|
||||
}
|
||||
|
||||
fn sys_mono_now_darwin() u64 {
|
||||
tm := C.mach_absolute_time()
|
||||
return mul_div(tm - start_time, time_base.numer, time_base.denom)
|
||||
}
|
||||
|
||||
fn mul_div(val, numer, denom u64) u64 {
|
||||
q := val / denom
|
||||
r := val % denom
|
||||
return q * numer + r * numer / denom
|
||||
}
|
@ -17,3 +17,25 @@ fn C.timegm(&tm) time_t
|
||||
fn make_unix_time(t C.tm) int {
|
||||
return int(C.timegm(&t))
|
||||
}
|
||||
|
||||
type time_t voidptr
|
||||
|
||||
// in most systems, these are __quad_t, which is an i64
|
||||
struct C.timespec {
|
||||
tv_sec i64
|
||||
tv_nsec i64
|
||||
}
|
||||
|
||||
// the first arg is defined in include/bits/types.h as `__S32_TYPE`, which is `int`
|
||||
fn C.clock_gettime(int, &C.timespec)
|
||||
|
||||
fn sys_mono_now() u64 {
|
||||
$if macos {
|
||||
return sys_mono_now_darwin()
|
||||
} $else {
|
||||
ts := C.timespec{}
|
||||
C.clock_gettime(C.CLOCK_MONOTONIC, &ts)
|
||||
return u64(ts.tv_sec) * 1_000_000_000 + u64(ts.tv_nsec)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,48 @@ struct C.tm {
|
||||
tm_sec int
|
||||
}
|
||||
|
||||
[typedef]
|
||||
struct C.LARGE_INTEGER {
|
||||
QuadPart i64
|
||||
}
|
||||
|
||||
const (
|
||||
// start_time is needed on Darwin and Windows because of potential overflows
|
||||
// Windows: don't store the LARGE_INTEGER, just the QuadPart
|
||||
start_time = init_win_time_start()
|
||||
freq_time = init_win_time_freq()
|
||||
)
|
||||
|
||||
fn C._mkgmtime(&C.tm) time_t
|
||||
|
||||
fn C.QueryPerformanceCounter(&C.LARGE_INTEGER) C.BOOL
|
||||
|
||||
fn C.QueryPerformanceFrequency(&C.LARGE_INTEGER) C.BOOL
|
||||
|
||||
fn make_unix_time(t C.tm) int {
|
||||
return int(C._mkgmtime(&t))
|
||||
}
|
||||
|
||||
fn init_win_time_freq() u64 {
|
||||
mut f := C.LARGE_INTEGER{}
|
||||
_ := C.QueryPerformanceFrequency(&f)
|
||||
return u64(f.QuadPart)
|
||||
}
|
||||
|
||||
fn init_win_time_start() u64 {
|
||||
mut s := C.LARGE_INTEGER{}
|
||||
_ := C.QueryPerformanceCounter(&s)
|
||||
return u64(s.QuadPart)
|
||||
}
|
||||
|
||||
fn sys_mono_now() u64 {
|
||||
mut tm := C.LARGE_INTEGER{}
|
||||
_ := C.QueryPerformanceCounter(&tm) // XP or later never fail
|
||||
return mul_div(u64(tm.QuadPart) - start_time, 1_000_000_000, freq_time)
|
||||
}
|
||||
|
||||
fn mul_div(val, numer, denom u64) u64 {
|
||||
q := val / denom
|
||||
r := val % denom
|
||||
return q * numer + r * numer / denom
|
||||
}
|
||||
|
@ -1,60 +0,0 @@
|
||||
// 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()}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user