108 lines
2.6 KiB
V
108 lines
2.6 KiB
V
module main
|
|
|
|
import os
|
|
import flag
|
|
import time
|
|
import scripting
|
|
|
|
struct CmdResult {
|
|
mut:
|
|
runs int
|
|
outputs []string
|
|
timings []int
|
|
}
|
|
struct Context {
|
|
mut:
|
|
count int
|
|
warmup int
|
|
show_help bool
|
|
show_result bool
|
|
verbose bool
|
|
commands []string
|
|
results []CmdResult
|
|
}
|
|
|
|
fn main(){
|
|
mut context := Context{}
|
|
context.parse_options()
|
|
context.run()
|
|
context.show_diff_summary()
|
|
context.show_stddev()
|
|
}
|
|
|
|
fn (mut context Context) parse_options() {
|
|
mut fp := flag.new_flag_parser(os.args)
|
|
fp.application(os.file_name(os.executable()))
|
|
fp.version('0.0.1')
|
|
fp.description('Repeat command(s) and collect statistics. NB: you have to quote each command.')
|
|
fp.arguments_description('CMD1 CMD2 ...')
|
|
fp.skip_executable()
|
|
fp.limit_free_args_to_at_least(1)
|
|
context.count = fp.int('count', `c`, 10, 'Repetition count')
|
|
context.warmup = fp.int('warmup', `w`, 2, 'Warmup runs')
|
|
context.show_help = fp.bool('help', `h`, false, 'Show this help screen.')
|
|
context.verbose = fp.bool('verbose', `v`, false, 'Be more verbose.')
|
|
context.show_result = fp.bool('result', `r`, true, 'Show the result too.')
|
|
if context.show_help {
|
|
println(fp.usage())
|
|
exit(0)
|
|
}
|
|
if context.verbose {
|
|
scripting.set_verbose(true)
|
|
}
|
|
context.commands = fp.finalize() or {
|
|
eprintln('Error: ' + err)
|
|
exit(1)
|
|
}
|
|
context.results = []CmdResult{ len: context.commands.len, init: CmdResult{} }
|
|
}
|
|
|
|
fn (mut context Context) run() {
|
|
print('')
|
|
for icmd, cmd in context.commands {
|
|
mut runs := 0
|
|
mut duration := 0
|
|
mut sum := 0
|
|
mut oldres := ''
|
|
if context.warmup > 0 {
|
|
for i in 1..context.warmup+1 {
|
|
print('\r warming up run: ${i:4}/${context.warmup:-4} for ${cmd:-50s} took ${duration:6} ms ...')
|
|
mut sw := time.new_stopwatch({})
|
|
os.exec(cmd) or { continue }
|
|
duration = int(sw.elapsed().milliseconds())
|
|
}
|
|
}
|
|
for i in 1..(context.count+1) {
|
|
avg := f64(sum)/f64(i)
|
|
print('\r average: ${avg:9.3f} ms | run: ${i:4}/${context.count:-4} | took ${duration:6} ms | cmd: ${cmd:-50s}')
|
|
if context.show_result {
|
|
print(' | result: ${oldres:-s}')
|
|
}
|
|
mut sw := time.new_stopwatch({})
|
|
res := os.exec(cmd) or {
|
|
eprintln('${i:10} failed runnning cmd: $cmd')
|
|
continue
|
|
}
|
|
duration = int(sw.elapsed().milliseconds())
|
|
if res.exit_code != 0 {
|
|
eprintln('${i:10} non 0 exit code for cmd: $cmd')
|
|
continue
|
|
}
|
|
context.results[icmd].outputs << res.output
|
|
context.results[icmd].timings << duration
|
|
sum += duration
|
|
runs++
|
|
oldres = res.output.replace('\n', ' ')
|
|
}
|
|
context.results[icmd].runs = runs
|
|
println('')
|
|
}
|
|
}
|
|
|
|
fn (mut context Context) show_diff_summary() {
|
|
// TODO
|
|
}
|
|
fn (mut context Context) show_stddev() {
|
|
// TODO
|
|
}
|