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