Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
2e6eab6
.
SimonCropp Nov 25, 2025
61be3e1
.
SimonCropp Nov 25, 2025
9547497
.
SimonCropp Nov 25, 2025
4fcfe7e
.
SimonCropp Nov 25, 2025
9cbf604
.
SimonCropp Nov 25, 2025
8ea715c
.
SimonCropp Nov 25, 2025
4500695
Update CrossChunkMatcher.cs
SimonCropp Nov 25, 2025
d5bd5b2
.
SimonCropp Nov 25, 2025
448915d
Update CrossChunkMatcher.cs
SimonCropp Nov 25, 2025
621a50e
.
SimonCropp Nov 25, 2025
d089ed1
Update DirectoryReplacements_StringBuilder.cs
SimonCropp Nov 25, 2025
d55ab13
.
SimonCropp Nov 25, 2025
6eec98f
Update CrossChunkMatcher.cs
SimonCropp Nov 25, 2025
bb269f9
.
SimonCropp Nov 25, 2025
d28a0fc
Update DateScrubber.cs
SimonCropp Nov 25, 2025
d89326b
Update src/Verify/Serialization/Scrubbers/CrossChunkMatcher.cs
SimonCropp Nov 29, 2025
e5b7655
Update src/Verify/Serialization/Scrubbers/DirectoryReplacements_Strin…
SimonCropp Nov 29, 2025
45cff61
Update src/Verify/Serialization/Scrubbers/DirectoryReplacements_Strin…
SimonCropp Nov 29, 2025
0eddccb
.
SimonCropp Nov 29, 2025
cc75e9c
.
SimonCropp Nov 29, 2025
19e4e72
Merge branch 'main' into CrossChunkMatcher2
SimonCropp Nov 29, 2025
6b6bbb0
Update CrossChunkMatcher.cs
SimonCropp Nov 30, 2025
2e84ea2
Update CrossChunkMatcher.cs
SimonCropp Nov 30, 2025
b1c5d9a
.
SimonCropp Nov 30, 2025
87f4760
.
SimonCropp Nov 30, 2025
e8e1263
Update CrossChunkMatcher.cs
SimonCropp Nov 30, 2025
33020a6
Update CrossChunkMatcherBenchmarks.cs
SimonCropp Nov 30, 2025
7003276
Update CrossChunkMatcherBenchmarks.cs
SimonCropp Nov 30, 2025
29b7f60
Merge branch 'main' into CrossChunkMatcher2
SimonCropp Nov 30, 2025
54105a1
Merge branch 'main' into CrossChunkMatcher2
SimonCropp Nov 30, 2025
6bc2108
Update CrossChunkMatcher.cs
SimonCropp Nov 30, 2025
f584fac
Merge branch 'main' into CrossChunkMatcher2
SimonCropp Nov 30, 2025
9c5d0f6
Update CrossChunkMatcher.cs
SimonCropp Nov 30, 2025
d2efaa3
Update CrossChunkMatcher.cs
SimonCropp Nov 30, 2025
7ce4241
Update CrossChunkMatcher.cs
SimonCropp Nov 30, 2025
b2711cc
.
SimonCropp Nov 30, 2025
e7b2874
Update CrossChunkMatcherBenchmarks.cs
SimonCropp Dec 1, 2025
90dc4a5
Update CrossChunkMatcher.cs
SimonCropp Dec 1, 2025
81dbc48
Update CrossChunkMatcher.cs
SimonCropp Dec 1, 2025
d3c9213
Update CrossChunkMatcher.cs
SimonCropp Dec 1, 2025
b5d8496
Update CrossChunkMatcher.cs
SimonCropp Dec 1, 2025
86973c9
Update CrossChunkMatcher.cs
SimonCropp Dec 1, 2025
4295148
Update DateScrubber.cs
SimonCropp Dec 1, 2025
b50e2ef
Update Extensions.cs
SimonCropp Dec 1, 2025
26cfb5d
Update Extensions.cs
SimonCropp Dec 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
263 changes: 263 additions & 0 deletions src/Benchmarks/CrossChunkMatcherBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
[MemoryDiagnoser]
[SimpleJob(warmupCount: 3, iterationCount: 5)]
public class CrossChunkMatcherBenchmarks
{
StringBuilder singleChunkSmall = null!;
StringBuilder singleChunkMedium = null!;
StringBuilder singleChunkLarge = null!;
StringBuilder multiChunkSmall = null!;
StringBuilder multiChunkMedium = null!;
StringBuilder multiChunkLarge = null!;

[GlobalSetup]
public void Setup()
{
// Single-chunk builders (created from string - fast path)
var smallText = BuildText(10);
var mediumText = BuildText(100);
var largeText = BuildText(1000);

singleChunkSmall = new(smallText);
singleChunkMedium = new(mediumText);
singleChunkLarge = new(largeText);

// Multi-chunk builders (built incrementally to force multiple chunks)
multiChunkSmall = BuildMultiChunk(10);
multiChunkMedium = BuildMultiChunk(100);
multiChunkLarge = BuildMultiChunk(1000);
}

static string BuildText(int iterations)
{
var builder = new StringBuilder();
for (var i = 0; i < iterations; i++)
{
builder.AppendLine("Hello <TAG>world</TAG> this is");
builder.AppendLine("a test with some <TAG>patterns</TAG> to match.");
}
return builder.ToString();
}

static StringBuilder BuildMultiChunk(int iterations)
{
var builder = new StringBuilder();
for (var i = 0; i < iterations; i++)
{
// Each Append can create separate chunks
builder.Append("Hello ");
builder.Append("<TAG>");
builder.Append("world");
builder.Append("</TAG>");
builder.AppendLine(" this is");
builder.Append("a test with some ");
builder.Append("<TAG>");
builder.Append("patterns");
builder.Append("</TAG>");
builder.AppendLine(" to match.");
}
return builder;
}

// Single-chunk benchmarks (fast path)
[Benchmark]
public void SingleChunk_Small()
{
var builder = new StringBuilder(singleChunkSmall.ToString());
CrossChunkMatcher.ReplaceAll(
builder,
maxLength: 20,
context: (string?)null,
matcher: static (content, _, _) =>
{
if (content.StartsWith("<TAG>"))
{
return new MatchResult(5, "[REPLACED]");
}
return null;
});
}

[Benchmark]
public void SingleChunk_Medium()
{
var builder = new StringBuilder(singleChunkMedium.ToString());
CrossChunkMatcher.ReplaceAll(
builder,
maxLength: 20,
context: (string?)null,
matcher: static (content, _, _) =>
{
if (content.StartsWith("<TAG>"))
{
return new MatchResult(5, "[REPLACED]");
}
return null;
});
}

[Benchmark]
public void SingleChunk_Large()
{
var builder = new StringBuilder(singleChunkLarge.ToString());
CrossChunkMatcher.ReplaceAll(
builder,
maxLength: 20,
context: (string?)null,
matcher: static (content, _, _) =>
{
if (content.StartsWith("<TAG>"))
{
return new MatchResult(5, "[REPLACED]");
}
return null;
});
}

// Multi-chunk benchmarks (complex path)
[Benchmark]
public void MultiChunk_Small()
{
var builder = new StringBuilder();
foreach (var chunk in multiChunkSmall.GetChunks())
{
builder.Append(chunk.Span);
}
CrossChunkMatcher.ReplaceAll(
builder,
maxLength: 20,
context: (string?)null,
matcher: static (content, _, _) =>
{
if (content.StartsWith("<TAG>"))
{
return new MatchResult(5, "[REPLACED]");
}
return null;
});
}

[Benchmark]
public void MultiChunk_Medium()
{
var builder = new StringBuilder();
foreach (var chunk in multiChunkMedium.GetChunks())
{
builder.Append(chunk.Span);
}
CrossChunkMatcher.ReplaceAll(
builder,
maxLength: 20,
context: (string?)null,
matcher: static (content, _, _) =>
{
if (content.StartsWith("<TAG>"))
{
return new MatchResult(5, "[REPLACED]");
}
return null;
});
}

[Benchmark]
public void MultiChunk_Large()
{
var builder = new StringBuilder();
foreach (var chunk in multiChunkLarge.GetChunks())
{
builder.Append(chunk.Span);
}
CrossChunkMatcher.ReplaceAll(
builder,
maxLength: 20,
context: (string?)null,
matcher: static (content, _, _) =>
{
if (content.StartsWith("<TAG>"))
{
return new MatchResult(5, "[REPLACED]");
}
return null;
});
}

// Edge cases
[Benchmark]
public void SingleChunk_NoMatches()
{
var builder = new StringBuilder(singleChunkMedium.ToString());
CrossChunkMatcher.ReplaceAll(
builder,
maxLength: 20,
context: (string?)null,
matcher: static (content, _, _) =>
{
if (content.StartsWith("<NOMATCH>"))
{
return new MatchResult(9, "[REPLACED]");
}
return null;
});
}

[Benchmark]
public void MultiChunk_NoMatches()
{
var builder = new StringBuilder();
foreach (var chunk in multiChunkMedium.GetChunks())
{
builder.Append(chunk.Span);
}
CrossChunkMatcher.ReplaceAll(
builder,
maxLength: 20,
context: (string?)null,
matcher: static (content, _, _) =>
{
if (content.StartsWith("<NOMATCH>"))
{
return new MatchResult(9, "[REPLACED]");
}
return null;
});
}

[Benchmark]
public void SingleChunk_ComplexPattern()
{
var builder = new StringBuilder(singleChunkMedium.ToString());
CrossChunkMatcher.ReplaceAll(
builder,
maxLength: 100,
context: (string?)null,
matcher: static (content, _, _) =>
{
if (content.StartsWith("<TAG>world</TAG>"))
{
return new MatchResult(16, "[COMPLEX]");
}
return null;
});
}

[Benchmark]
public void MultiChunk_ComplexPattern()
{
var builder = new StringBuilder();
foreach (var chunk in multiChunkMedium.GetChunks())
{
builder.Append(chunk.Span);
}
CrossChunkMatcher.ReplaceAll(
builder,
maxLength: 100,
context: (string?)null,
matcher: static (content, _, _) =>
{
if (content.StartsWith("<TAG>world</TAG>"))
{
return new MatchResult(16, "[COMPLEX]");
}
return null;
});
}
}
3 changes: 2 additions & 1 deletion src/Benchmarks/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
global using BenchmarkDotNet.Attributes;
global using System.Text;
global using BenchmarkDotNet.Attributes;
global using BenchmarkDotNet.Running;
global using VerifyTests;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
XYXYXY
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
MatchFound: true,
Position: 8000,
Context: aaaaaaaaaaFOUNDbbbbbbbbbb
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
replaced x r y
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
emptyString
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
MatchCount: 5
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
StringResult
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ResultString
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
MatchCount: 2
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bar bar bar baz bar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello World
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bbbb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
MatchFound: true,
OriginalPatternExists: false,
Note: Pattern spanning 4 chunks should now be detected
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
MatchFound: true,
OriginalPatternExists: false,
Note: Pattern spanning 3 chunks should now be detected
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
MatchFound: true,
OriginalPatternExists: false,
Note: Pattern spanning 3 chunks should now be detected
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
MatchFound: true,
ExpectedPosition: 8000,
ActualPosition: 8000
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello Universe
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x b x c x
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
0,
3,
6,
9,
12,
15
]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
animal animal animal animal
Loading