001 Notes
zlob Optimization: Faster In-Memory Glob Matching Without More Layers
0. Abstract
the paths are already in memory
the caller needs to scan a lot of them
the matcher should stop doing avoidable work before reaching for more machinery
the code got faster because it did less work
and the benchmark matrix was strict enough to reject the clever ideas that lost
1. Baseline: In-Memory Matching Still Wastes Time If The Shape Is Wrong
2. Widening The Suffix Fast Path Was The First Big Win
Old Shape
// SingleSuffixMatcher works for suffixes up to 4 bytes.
if (suffix.len >= 1 and suffix.len <= 4) {
return .{ SingleSuffixMatcher.init(suffix), suffix_matcher };
}
New Shape
// SingleSuffixMatcher works for suffixes up to 8 bytes.
if (suffix.len >= 1 and suffix.len <= 8) {
return .{ SingleSuffixMatcher.init(suffix), suffix_matcher };
}
Measured Result
| Workload | Baseline | After widened suffix path | Speedup |
|---|---|---|---|
brace_multi_mixed_long_deep, 16384 paths | 1423.799 us/run | 164.045 us/run | 8.68x |
3. Full-Path Tail Comparison Beat Repeated Basename Rescans
Measured Result
| Workload | Before | After | Speedup |
|---|---|---|---|
brace_multi_mixed_long_deep, 16384 paths | 164.045 us/run | 127.016 us/run | 1.29x |
4. Recursive Matching Needed Earlier Rejection, Not More Heroics
Measured Result
| Workload | Before | After | Speedup |
|---|---|---|---|
recursive_long_suffix_prefilter, 131072 paths | 926.027 us/run | 838.916 us/run | 1.10x |
5. Optional Output Materialization Was A Real API-Level Win
Reusable Output
| Workload | Owned result path | Reusable output | Speedup |
|---|---|---|---|
brace_multi_mixed_long_deep, 131072 paths, warm | 954.568 us/run | 471.258 us/run | 2.03x |
Count-Only
| Workload | Reusable output | Count-only | Speedup |
|---|---|---|---|
single_long_suffix_lock, 131072 paths, warm | 239.021 us/run | 178.466 us/run | 1.34x |
6. Threading Was Valuable Only After The Serial Path Was Lean
Count-Only Parallelism
Reusable-Output Parallelism
Break-Even Matters More Than The Headline
7. The Rollbacks Matter As Much As The Wins
| Rejected change | Workload | Before | After |
|---|---|---|---|
| BLAS-like batch-8 matching | single_short_suffix_zig, 131072 paths | 791.748 us/run | 906.225 us/run |
std.mem.indexOf component search | filtered recursive, warm count-only | 838.916 us/run | 1951.303 us/run |
| SIMD separator scan | reusable-output warm | 977.884 us/run | 1448.611 us/run |
8. Takeaway
first make the serial path stop wasting work
then give callers cheaper contracts
then parallelize only the cases large enough to deserve it
Comments