also looking at this
Port to latest zig-master
#2
53 files
+1149
-1017
| @@ -1,15 +1,17 @@ | ||
| 1 | 1 | const std = ; |
| 2 | const Clock = std.Io.Clock; | |
| 2 | 3 | |
| 3 | 4 | /// Performance profiling and metrics tracking for regex operations |
| 4 | 5 | pub const Profiler = struct { |
| 5 | 6 | allocator: std.mem.Allocator, |
| 7 | io: std.Io, | |
| 6 | 8 | enabled: bool, |
| 7 | 9 | metrics: Metrics, |
| 8 | start_time: ?std.time.Instant, | |
| 10 | start_time: ?std.Io.Timestamp, | |
| 9 | 11 | |
| 10 | 12 | pub const Metrics = struct { |
| 11 | compilation_time_ns: u64 = 0, | |
| 12 | match_time_ns: u64 = 0, | |
| 13 | compilation_time_ns: i96 = 0, | |
| 14 | match_time_ns: i96 = 0, | |
| 13 | 15 | match_count: usize = 0, |
| 14 | 16 | nfa_states_created: usize = 0, |
| 15 | 17 | backtrack_count: usize = 0, |
| @@ -25,13 +27,8 @@ pub const Profiler = struct { | ||
| 25 | 27 | |
| 26 | 28 | pub fn format( |
| 27 | 29 | self: Metrics, |
| 28 | comptime fmt: []const u8, | |
| 29 | options: std.fmt.FormatOptions, | |
| 30 | writer: anytype, | |
| 30 | writer: *std.Io.Writer, | |
| 31 | 31 | ) !void { |
| 32 | _ = fmt; | |
| 33 | _ = options; | |
| 34 | ||
| 35 | 32 | try writer.writeAll("\n=== Regex Performance Metrics ===\n"); |
| 36 | 33 | try writer.print("Compilation time: {d}μs\n", .{self.compilation_time_ns / 1000}); |
| 37 | 34 | try writer.print("Match time: {d}μs\n", .{self.match_time_ns / 1000}); |
| @@ -49,41 +46,40 @@ pub const Profiler = struct { | ||
| 49 | 46 | } |
| 50 | 47 | }; |
| 51 | 48 | |
| 52 | pub fn init(allocator: std.mem.Allocator, enabled: bool) Profiler { | |
| 49 | pub fn init(allocator: std.mem.Allocator, io: std.Io, enabled: bool) Profiler { | |
| 53 | 50 | return .{ |
| 51 | .io = io, | |
| 54 | 52 | .allocator = allocator, |
| 55 | 53 | .enabled = enabled, |
| 56 | 54 | .metrics = Metrics{}, |
| 57 | .start_time = if (enabled) std.time.Instant.now() catch null else null, | |
| 55 | .start_time = if (enabled) Clock.awake.now(io) else null, | |
| 58 | 56 | }; |
| 59 | 57 | } |
| 60 | 58 | |
| 61 | 59 | /// Start timing a compilation phase |
| 62 | 60 | pub fn startCompilation(self: *Profiler) void { |
| 63 | 61 | if (!self.enabled) return; |
| 64 | self.start_time = std.time.Instant.now() catch null; | |
| 62 | self.start_time = Clock.awake.now(self.io); | |
| 65 | 63 | } |
| 66 | 64 | |
| 67 | 65 | /// End timing a compilation phase |
| 68 | 66 | pub fn endCompilation(self: *Profiler) void { |
| 69 | 67 | if (!self.enabled) return; |
| 70 | 68 | 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); | |
| 69 | self.metrics.compilation_time_ns += start.untilNow(self.io, Clock.awake).toNanoseconds(); | |
| 73 | 70 | } |
| 74 | 71 | |
| 75 | 72 | /// Start timing a match operation |
| 76 | 73 | pub fn startMatch(self: *Profiler) void { |
| 77 | 74 | if (!self.enabled) return; |
| 78 | self.start_time = std.time.Instant.now() catch null; | |
| 75 | self.start_time = Clock.awake.now(self.io); | |
| 79 | 76 | } |
| 80 | 77 | |
| 81 | 78 | /// End timing a match operation |
| 82 | 79 | pub fn endMatch(self: *Profiler) void { |
| 83 | 80 | if (!self.enabled) return; |
| 84 | 81 | 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); | |
| 82 | self.metrics.match_time_ns += start.untilNow(self.io, .awake).toNanoseconds(); | |
| 87 | 83 | self.metrics.match_count += 1; |
| 88 | 84 | } |
| 89 | 85 | |
| @@ -142,7 +138,7 @@ pub const Profiler = struct { | ||
| 142 | 138 | /// Reset all metrics |
| 143 | 139 | pub fn reset(self: *Profiler) void { |
| 144 | 140 | self.metrics.reset(); |
| 145 | self.start_time = if (self.enabled) std.time.Instant.now() catch null else null; | |
| 141 | self.start_time = if (self.enabled) Clock.now(self.io) else null; | |
| 146 | 142 | } |
| 147 | 143 | |
| 148 | 144 | /// Print metrics to stderr |
| @@ -156,7 +152,7 @@ pub const Profiler = struct { | ||
| 156 | 152 | pub const ScopedTimer = struct { |
| 157 | 153 | profiler: *Profiler, |
| 158 | 154 | timer_type: TimerType, |
| 159 | start: ?std.time.Instant, | |
| 155 | start: ?std.Io.Timestamp, | |
| 160 | 156 | |
| 161 | 157 | pub const TimerType = enum { |
| 162 | 158 | compilation, |
| @@ -167,15 +163,14 @@ pub const ScopedTimer = struct { | ||
| 167 | 163 | return .{ |
| 168 | 164 | .profiler = profiler, |
| 169 | 165 | .timer_type = timer_type, |
| 170 | .start = if (profiler.enabled) std.time.Instant.now() catch null else null, | |
| 166 | .start = if (profiler.enabled) Clock.awake.now(profiler.io) else null, | |
| 171 | 167 | }; |
| 172 | 168 | } |
| 173 | 169 | |
| 174 | 170 | pub fn deinit(self: *ScopedTimer) void { |
| 175 | 171 | if (!self.profiler.enabled) return; |
| 176 | 172 | const start = self.start orelse return; |
| 177 | const now = std.time.Instant.now() catch return; | |
| 178 | const elapsed = now.since(start); | |
| 173 | const elapsed = start.untilNow(self.profiler.io, Clock.awake).toNanoseconds(); | |
| 179 | 174 | switch (self.timer_type) { |
| 180 | 175 | .compilation => self.profiler.metrics.compilation_time_ns += elapsed, |
| 181 | 176 | .match => { |
| @@ -188,7 +183,7 @@ pub const ScopedTimer = struct { | ||
| 188 | 183 | |
| 189 | 184 | test "profiler basic operations" { |
| 190 | 185 | const allocator = std.testing.allocator; |
| 191 | var profiler = Profiler.init(allocator, true); | |
| 186 | var profiler = Profiler.init(allocator, std.testing.io, true); | |
| 192 | 187 | |
| 193 | 188 | profiler.startCompilation(); |
| 194 | 189 | // Do some work (just loop to consume time) |
| @@ -210,7 +205,7 @@ test "profiler basic operations" { | ||
| 210 | 205 | |
| 211 | 206 | test "scoped timer" { |
| 212 | 207 | const allocator = std.testing.allocator; |
| 213 | var profiler = Profiler.init(allocator, true); | |
| 208 | var profiler = Profiler.init(allocator, std.testing.io, true); | |
| 214 | 209 | |
| 215 | 210 | { |
| 216 | 211 | var timer = ScopedTimer.init(&profiler, .match); |