ReviewOS

also looking at this

zig-utils/zig-regex

Port to latest zig-master

#2
Closed armagidon-exception wants to merge main into main
53 files +1149 -1017
benchmarks/prefix_optimization.zigmodified+24-27
Changes to benchmarks/prefix_optimization.zig
@@ -1,7 +1,9 @@
11const std = ;
2const Clock = std.Io.Clock;
23const Regex = .Regex;
34
4pub fn main() !void {
5pub fn main(init: std.process.Init) !void {
6 const io = init.io;
57 var gpa = std.heap.GeneralPurposeAllocator(.{}){};
68 defer _ = gpa.deinit();
79 const allocator = gpa.allocator();
@@ -14,7 +16,7 @@ pub fn main() !void {
1416 // Test 1: Pattern with literal prefix (should use optimization)
1517 {
1618 std.debug.print("Test 1: Literal prefix optimization (FOUND_IT!)...\n", .{});
17 var regex = try Regex.compile(allocator, "FOUND_IT!");
19 var regex = try Regex.compile(allocator, io, "FOUND_IT!");
1820 defer regex.deinit();
1921
2022 // Print optimization info
@@ -24,8 +26,7 @@ pub fn main() !void {
2426 std.debug.print(" ✗ No literal prefix found\n", .{});
2527 }
2628
27 var timer = try std.time.Timer.start();
28 const start = timer.read();
29 const start = Clock.awake.now(io);
2930
3031 const iterations: usize = 10000;
3132 var i: usize = 0;
@@ -36,8 +37,8 @@ pub fn main() !void {
3637 }
3738 }
3839
39 const elapsed = timer.read() - start;
40 const avg_ns = elapsed / iterations;
40 const elapsed = start.untilNow(io, .awake).toNanoseconds();
41 const avg_ns = @divExact(elapsed, iterations);
4142 std.debug.print(" {d} iterations in {d:.2}ms ({d:.2}µs/op)\n\n", .{
4243 iterations,
4344 @as(f64, @floatFromInt(elapsed)) / 1_000_000.0,
@@ -48,7 +49,7 @@ pub fn main() !void {
4849 // Test 2: Pattern without useful prefix (no optimization) - using fewer iterations
4950 {
5051 std.debug.print("Test 2: No prefix optimization (.*FOUND)...\n", .{});
51 var regex = try Regex.compile(allocator, ".*FOUND");
52 var regex = try Regex.compile(allocator, init.io, ".*FOUND");
5253 defer regex.deinit();
5354
5455 if (regex.opt_info.literal_prefix) |prefix| {
@@ -57,8 +58,7 @@ pub fn main() !void {
5758 std.debug.print(" ✗ No literal prefix found (slower performance expected)\n", .{});
5859 }
5960
60 var timer = try std.time.Timer.start();
61 const start = timer.read();
61 const start = Clock.awake.now(init.io);
6262
6363 // Use fewer iterations since this is much slower without optimization
6464 const iterations: usize = 100;
@@ -70,8 +70,8 @@ pub fn main() !void {
7070 }
7171 }
7272
73 const elapsed = timer.read() - start;
74 const avg_ns = elapsed / iterations;
73 const elapsed = start.untilNow(io, .awake).toNanoseconds();
74 const avg_ns = @divExact(elapsed, iterations);
7575 std.debug.print(" {d} iterations in {d:.2}ms ({d:.2}µs/op)\n\n", .{
7676 iterations,
7777 @as(f64, @floatFromInt(elapsed)) / 1_000_000.0,
@@ -83,7 +83,7 @@ pub fn main() !void {
8383 {
8484 std.debug.print("Test 3: Prefix with complex suffix (hello.*world)...\n", .{});
8585 const text_with_hello = "blah blah " ** 50 ++ "hello there world";
86 var regex = try Regex.compile(allocator, "hello.*world");
86 var regex = try Regex.compile(allocator, init.io, "hello.*world");
8787 defer regex.deinit();
8888
8989 if (regex.opt_info.literal_prefix) |prefix| {
@@ -92,8 +92,7 @@ pub fn main() !void {
9292 std.debug.print(" ✗ No literal prefix found\n", .{});
9393 }
9494
95 var timer = try std.time.Timer.start();
96 const start = timer.read();
95 const start = Clock.awake.now(init.io);
9796
9897 const iterations: usize = 10000;
9998 var i: usize = 0;
@@ -104,8 +103,8 @@ pub fn main() !void {
104103 }
105104 }
106105
107 const elapsed = timer.read() - start;
108 const avg_ns = elapsed / iterations;
106 const elapsed = start.untilNow(init.io, .awake).toNanoseconds();
107 const avg_ns = @divExact(elapsed, iterations);
109108 std.debug.print(" {d} iterations in {d:.2}ms ({d:.2}µs/op)\n\n", .{
110109 iterations,
111110 @as(f64, @floatFromInt(elapsed)) / 1_000_000.0,
@@ -116,7 +115,7 @@ pub fn main() !void {
116115 // Test 4: Anchored patterns
117116 {
118117 std.debug.print("Test 4: Start-anchored pattern (^hello)...\n", .{});
119 var regex = try Regex.compile(allocator, "^hello");
118 var regex = try Regex.compile(allocator, init.io, "^hello");
120119 defer regex.deinit();
121120
122121 if (regex.opt_info.anchored_start) {
@@ -127,8 +126,7 @@ pub fn main() !void {
127126 }
128127
129128 const text = "hello world";
130 var timer = try std.time.Timer.start();
131 const start = timer.read();
129 const start = Clock.awake.now(init.io);
132130
133131 const iterations: usize = 10000;
134132 var i: usize = 0;
@@ -136,8 +134,8 @@ pub fn main() !void {
136134 _ = try regex.isMatch(text);
137135 }
138136
139 const elapsed = timer.read() - start;
140 const avg_ns = elapsed / iterations;
137 const elapsed = start.untilNow(init.io, .awake).toNanoseconds();
138 const avg_ns = @divExact(elapsed, iterations);
141139 std.debug.print(" {d} iterations in {d:.2}ms ({d:.2}µs/op)\n\n", .{
142140 iterations,
143141 @as(f64, @floatFromInt(elapsed)) / 1_000_000.0,
@@ -149,15 +147,14 @@ pub fn main() !void {
149147 {
150148 std.debug.print("Test 5: Email pattern (user@example.com)...\n", .{});
151149 const email_text = "Contact us at " ++ ("some filler text here. " ** 20) ++ "user@example.com for support";
152 var regex = try Regex.compile(allocator, "user@example.com");
150 var regex = try Regex.compile(allocator, init.io, "user@example.com");
153151 defer regex.deinit();
154152
155153 if (regex.opt_info.literal_prefix) |prefix| {
156 std.debug.print(" ✓ Using literal prefix: \"{s}\" (min_len={d})\n", .{prefix, regex.opt_info.min_length});
154 std.debug.print(" ✓ Using literal prefix: \"{s}\" (min_len={d})\n", .{ prefix, regex.opt_info.min_length });
157155 }
158156
159 var timer = try std.time.Timer.start();
160 const start = timer.read();
157 const start = Clock.awake.now(init.io);
161158
162159 const iterations: usize = 10000;
163160 var i: usize = 0;
@@ -168,8 +165,8 @@ pub fn main() !void {
168165 }
169166 }
170167
171 const elapsed = timer.read() - start;
172 const avg_ns = elapsed / iterations;
168 const elapsed = start.untilNow(init.io, .awake).toNanoseconds();
169 const avg_ns = @divExact(elapsed , iterations);
173170 std.debug.print(" {d} iterations in {d:.2}ms ({d:.2}µs/op)\n\n", .{
174171 iterations,
175172 @as(f64, @floatFromInt(elapsed)) / 1_000_000.0,