vxx2 / vlib / v3 / bench / bench.v
94 lines · 83 sloc · 2.15 KB · 0e30f8d2f2cf6ed81ee9cebe949190dc76b548c9
Raw
1module bench
2
3import os
4import time
5
6// C.getrusage declares the C getrusage symbol used by bench.
7fn C.getrusage(who int, usage voidptr) int
8
9// Step represents step data used by bench.
10pub struct Step {
11pub:
12 name string
13 time_us i64
14 ram_kb i64
15}
16
17// Bench represents bench data used by bench.
18pub struct Bench {
19mut:
20 steps []Step
21 total_sw time.StopWatch
22 step_sw time.StopWatch
23}
24
25// new creates a new value for bench.
26pub fn new() Bench {
27 return Bench{
28 total_sw: time.new_stopwatch()
29 step_sw: time.new_stopwatch()
30 }
31}
32
33// step records a serial pipeline step.
34pub fn (mut b Bench) step(name string) {
35 b.step_parallel(name, false)
36}
37
38// step_parallel records a pipeline step, appending "(parallel)" to its name
39// when the step actually ran across threads.
40pub fn (mut b Bench) step_parallel(name string, parallel bool) {
41 elapsed_us := b.step_sw.elapsed().microseconds()
42 ram_mb := f64(current_rss_kb()) / 1024.0
43 ms := f64(elapsed_us) / 1000.0
44 label := if parallel { '${name} (parallel)' } else { name }
45 println(' ${label:-20s} ${ms:8.2f} ms ${ram_mb:6.0f} MB resident RAM')
46 b.steps << Step{
47 name: label
48 time_us: elapsed_us
49 ram_kb: i64(ram_mb * 1024)
50 }
51 b.step_sw.restart()
52}
53
54// print_report updates print report state for Bench.
55pub fn (b &Bench) print_report() {
56 total_ms := f64(b.total_sw.elapsed().microseconds()) / 1000.0
57 println(' ${'total':-20s} ${total_ms:8.2f} ms')
58 println('')
59}
60
61// current_rss_kb returns current rss kb data for bench.
62fn current_rss_kb() i64 {
63 $if macos {
64 return macos_peak_rss_kb()
65 }
66 $if linux {
67 return linux_rss_kb()
68 }
69 return 0
70}
71
72// macos_peak_rss_kb supports macos peak rss kb handling for bench.
73fn macos_peak_rss_kb() i64 {
74 mut usage := [256]u8{}
75 if C.getrusage(0, &usage[0]) == 0 {
76 ru_maxrss := unsafe { *(&i64(&usage[32])) }
77 return ru_maxrss / 1024
78 }
79 return 0
80}
81
82// linux_rss_kb supports linux rss kb handling for bench.
83fn linux_rss_kb() i64 {
84 content := os.read_file('/proc/self/status') or { return 0 }
85 for line in content.split('\n') {
86 if line.starts_with('VmRSS:') {
87 parts := line.split_any(' \t').filter(it.len > 0)
88 if parts.len >= 2 {
89 return parts[1].i64()
90 }
91 }
92 }
93 return 0
94}
95