also looking at this
Migrate to zig 0.16
#5
13 files
+222
-239
Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.
| @@ -5,11 +5,11 @@ pub const Profiler = struct { | ||
| 5 | 5 | allocator: std.mem.Allocator, |
| 6 | 6 | enabled: bool, |
| 7 | 7 | metrics: Metrics, |
| 8 | start_time: ?std.time.Instant, | |
| 8 | start_time: ?std.Io.Timestamp, | |
| 9 | 9 | |
| 10 | 10 | pub const Metrics = struct { |
| 11 | compilation_time_ns: u64 = 0, | |
| 12 | match_time_ns: u64 = 0, | |
| 11 | compilation_time_ns: i96 = 0, | |
| 12 | match_time_ns: i96 = 0, | |
| 13 | 13 | match_count: usize = 0, |
| 14 | 14 | nfa_states_created: usize = 0, |
| 15 | 15 | backtrack_count: usize = 0, |
| @@ -49,41 +49,42 @@ pub const Profiler = struct { | ||
| 49 | 49 | } |
| 50 | 50 | }; |
| 51 | 51 | |
| 52 | pub fn init(allocator: std.mem.Allocator, enabled: bool) Profiler { | |
| 52 | pub fn init(allocator: std.mem.Allocator, io: std.Io, enabled: bool) Profiler { | |
| 53 | 53 | return .{ |
| 54 | 54 | .allocator = allocator, |
| 55 | 55 | .enabled = enabled, |
| 56 | 56 | .metrics = Metrics{}, |
| 57 | .start_time = if (enabled) std.time.Instant.now() catch null else null, | |
| 57 | // TODO: No clue what to actually pass as a clock | |
| 58 | .start_time = if (enabled) std.Io.Timestamp.now(io, .real) else null, | |
| 58 | 59 | }; |
| 59 | 60 | } |
| 60 | 61 | |
| 61 | 62 | /// Start timing a compilation phase |
| 62 | pub fn startCompilation(self: *Profiler) void { | |
| 63 | pub fn startCompilation(self: *Profiler, io: std.Io) void { | |
| 63 | 64 | if (!self.enabled) return; |
| 64 | self.start_time = std.time.Instant.now() catch null; | |
| 65 | self.start_time = std.Io.Timestamp.now(io, .real); | |
| 65 | 66 | } |
| 66 | 67 | |
| 67 | 68 | /// End timing a compilation phase |
| 68 | pub fn endCompilation(self: *Profiler) void { | |
| 69 | pub fn endCompilation(self: *Profiler, io: std.Io) void { | |
| 69 | 70 | if (!self.enabled) return; |
| 70 | 71 | const start = self.start_time orelse return; |
| 71 | const now = std.time.Instant.now() catch return; | |
| 72 | self.metrics.compilation_time_ns += now.since(start); | |
| 72 | const now = std.Io.Timestamp.now(io, .real); | |
| 73 | self.metrics.compilation_time_ns += start.durationTo(now).nanoseconds; | |
| 73 | 74 | } |
| 74 | 75 | |
| 75 | 76 | /// Start timing a match operation |
| 76 | pub fn startMatch(self: *Profiler) void { | |
| 77 | pub fn startMatch(self: *Profiler, io: std.Io) void { | |
| 77 | 78 | if (!self.enabled) return; |
| 78 | self.start_time = std.time.Instant.now() catch null; | |
| 79 | self.start_time = std.Io.Timestamp.now(io, .real); | |
| 79 | 80 | } |
| 80 | 81 | |
| 81 | 82 | /// End timing a match operation |
| 82 | pub fn endMatch(self: *Profiler) void { | |
| 83 | pub fn endMatch(self: *Profiler, io: std.Io) void { | |
| 83 | 84 | if (!self.enabled) return; |
| 84 | 85 | const start = self.start_time orelse return; |
| 85 | const now = std.time.Instant.now() catch return; | |
| 86 | self.metrics.match_time_ns += now.since(start); | |
| 86 | const now = std.Io.Timestamp.now(io, .real); | |
| 87 | self.metrics.match_time_ns += start.durationTo(now).nanoseconds; | |
| 87 | 88 | self.metrics.match_count += 1; |
| 88 | 89 | } |
| 89 | 90 | |
| @@ -140,9 +141,9 @@ pub const Profiler = struct { | ||
| 140 | 141 | } |
| 141 | 142 | |
| 142 | 143 | /// Reset all metrics |
| 143 | pub fn reset(self: *Profiler) void { | |
| 144 | pub fn reset(self: *Profiler, io: std.Io) void { | |
| 144 | 145 | self.metrics.reset(); |
| 145 | self.start_time = if (self.enabled) std.time.Instant.now() catch null else null; | |
| 146 | self.start_time = if (self.enabled) std.Io.Timestamp.now(io, .real); | |
| 146 | 147 | } |
| 147 | 148 | |
| 148 | 149 | /// Print metrics to stderr |
| @@ -156,26 +157,26 @@ pub const Profiler = struct { | ||
| 156 | 157 | pub const ScopedTimer = struct { |
| 157 | 158 | profiler: *Profiler, |
| 158 | 159 | timer_type: TimerType, |
| 159 | start: ?std.time.Instant, | |
| 160 | start: ?std.Io.Timestamp, | |
| 160 | 161 | |
| 161 | 162 | pub const TimerType = enum { |
| 162 | 163 | compilation, |
| 163 | 164 | match, |
| 164 | 165 | }; |
| 165 | 166 | |
| 166 | pub fn init(profiler: *Profiler, timer_type: TimerType) ScopedTimer { | |
| 167 | pub fn init(profiler: *Profiler, io: std.Io, timer_type: TimerType) ScopedTimer { | |
| 167 | 168 | return .{ |
| 168 | 169 | .profiler = profiler, |
| 169 | 170 | .timer_type = timer_type, |
| 170 | .start = if (profiler.enabled) std.time.Instant.now() catch null else null, | |
| 171 | .start = if (profiler.enabled) std.Io.Timestamp.now(io, .real) else null, | |
| 171 | 172 | }; |
| 172 | 173 | } |
| 173 | 174 | |
| 174 | pub fn deinit(self: *ScopedTimer) void { | |
| 175 | pub fn deinit(self: *ScopedTimer, io: std.Io) void { | |
| 175 | 176 | if (!self.profiler.enabled) return; |
| 176 | 177 | const start = self.start orelse return; |
| 177 | const now = std.time.Instant.now() catch return; | |
| 178 | const elapsed = now.since(start); | |
| 178 | const now = std.Io.Timestamp.now(io, .real); | |
| 179 | const elapsed = start.durationTo(now).nanoseconds; | |
| 179 | 180 | switch (self.timer_type) { |
| 180 | 181 | .compilation => self.profiler.metrics.compilation_time_ns += elapsed, |
| 181 | 182 | .match => { |
| @@ -188,7 +189,8 @@ pub const ScopedTimer = struct { | ||
| 188 | 189 | |
| 189 | 190 | test "profiler basic operations" { |
| 190 | 191 | const allocator = std.testing.allocator; |
| 191 | var profiler = Profiler.init(allocator, true); | |
| 192 | const io = std.testing.io; | |
| 193 | var profiler = Profiler.init(allocator, io, true); | |
| 192 | 194 | |
| 193 | 195 | profiler.startCompilation(); |
| 194 | 196 | // Do some work (just loop to consume time) |
| @@ -210,7 +212,8 @@ test "profiler basic operations" { | ||
| 210 | 212 | |
| 211 | 213 | test "scoped timer" { |
| 212 | 214 | const allocator = std.testing.allocator; |
| 213 | var profiler = Profiler.init(allocator, true); | |
| 215 | const io = std.testing.io; | |
| 216 | var profiler = Profiler.init(allocator, io, true); | |
| 214 | 217 | |
| 215 | 218 | { |
| 216 | 219 | var timer = ScopedTimer.init(&profiler, .match); |