Skip to content

Commit fce9cdb

Browse files
committed
Refactor benchmarks
1 parent 5873c3b commit fce9cdb

File tree

6 files changed

+262
-20
lines changed

6 files changed

+262
-20
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
using System.Text.RegularExpressions;
2+
using BenchmarkDotNet.Attributes;
3+
using StreamRegex.Extensions;
4+
using StreamRegex.Lib.DFA;
5+
using StreamRegex.Lib.NFA;
6+
7+
namespace StreamRegex.Benchmarks;
8+
[MemoryDiagnoser]
9+
public class BufferSizeBenchmarks
10+
{
11+
private readonly Regex _compiled;
12+
private const string Pattern = "racecar";
13+
private Stream _stream = new MemoryStream();
14+
public BufferSizeBenchmarks()
15+
{
16+
_compiled = new Regex(Pattern, RegexOptions.Compiled);
17+
}
18+
19+
[IterationSetup]
20+
public void IterationSetup()
21+
{
22+
_stream = File.OpenRead(TestFileName);
23+
}
24+
25+
[IterationCleanup]
26+
public void IterationCleanup()
27+
{
28+
_stream.Dispose();
29+
}
30+
31+
//[Params("TargetStart.txt","TargetMiddle.txt","TargetEnd.txt")]
32+
[Params("175MB.txt")]
33+
public string TestFileName { get; set; }
34+
35+
[BenchmarkCategory("Regex")]
36+
[Benchmark]
37+
public void CompiledRegex()
38+
{
39+
var content = new StreamReader(_stream).ReadToEnd();
40+
if (!_compiled.IsMatch(content))
41+
{
42+
throw new Exception($"The regex didn't match.");
43+
}
44+
}
45+
46+
[BenchmarkCategory("Regex")]
47+
[Benchmark]
48+
public void RegexExtension()
49+
{
50+
var content = new StreamReader(_stream);
51+
if (!_compiled.IsMatch(content))
52+
{
53+
throw new Exception($"The regex didn't match.");
54+
}
55+
}
56+
57+
[BenchmarkCategory("Contains")]
58+
[Benchmark(Baseline = true)]
59+
60+
public void SimpleString()
61+
{
62+
var match = new StreamReader(_stream).ReadToEnd().IndexOf("racecar");
63+
if (match == -1)
64+
{
65+
throw new Exception($"The regex didn't match.");
66+
}
67+
}
68+
69+
[BenchmarkCategory("Contains")]
70+
[Benchmark]
71+
public void StringExtension()
72+
{
73+
var content = new StreamReader(_stream);
74+
var match = content.IndexOf("racecar");
75+
if (match == -1)
76+
{
77+
throw new Exception($"The regex didn't match.");
78+
}
79+
}
80+
81+
82+
// [Benchmark]
83+
public void StateMachine()
84+
{
85+
var stateMachine = StateMachineFactory.CreateStateMachine(Pattern);
86+
if (stateMachine.GetFirstMatchPosition(_stream) == -1)
87+
{
88+
throw new Exception("The regex didn't match");
89+
}
90+
}
91+
92+
// [Benchmark]
93+
public void NFAStateMachine()
94+
{
95+
var stateMachine = NfaStateMachineFactory.CreateStateMachine(Pattern);
96+
var match = stateMachine.Match(_stream);
97+
if (match is null)
98+
{
99+
throw new Exception("The regex didn't match");
100+
}
101+
}
102+
}

StreamRegex.Benchmarks/PerformanceVsStandard.cs renamed to StreamRegex.Benchmarks/LargeFileBenchmarks.cs

+38-11
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ public void IterationCleanup()
3232
[Params("175MB.txt")]
3333
public string TestFileName { get; set; }
3434

35-
[Benchmark(Baseline = true)]
35+
[BenchmarkCategory("Regex")]
36+
[Benchmark]
3637
public void CompiledRegex()
3738
{
3839
var content = new StreamReader(_stream).ReadToEnd();
@@ -41,7 +42,43 @@ public void CompiledRegex()
4142
throw new Exception($"The regex didn't match.");
4243
}
4344
}
45+
46+
[BenchmarkCategory("Regex")]
47+
[Benchmark]
48+
public void RegexExtension()
49+
{
50+
var content = new StreamReader(_stream);
51+
if (!_compiled.IsMatch(content))
52+
{
53+
throw new Exception($"The regex didn't match.");
54+
}
55+
}
56+
57+
[BenchmarkCategory("Contains")]
58+
[Benchmark(Baseline = true)]
4459

60+
public void SimpleString()
61+
{
62+
var match = new StreamReader(_stream).ReadToEnd().IndexOf("racecar");
63+
if (match == -1)
64+
{
65+
throw new Exception($"The regex didn't match.");
66+
}
67+
}
68+
69+
[BenchmarkCategory("Contains")]
70+
[Benchmark]
71+
public void StringExtension()
72+
{
73+
var content = new StreamReader(_stream);
74+
var match = content.IndexOf("racecar");
75+
if (match == -1)
76+
{
77+
throw new Exception($"The regex didn't match.");
78+
}
79+
}
80+
81+
4582
// [Benchmark]
4683
public void StateMachine()
4784
{
@@ -62,14 +99,4 @@ public void NFAStateMachine()
6299
throw new Exception("The regex didn't match");
63100
}
64101
}
65-
66-
[Benchmark]
67-
public void RegexExtension()
68-
{
69-
var content = new StreamReader(_stream);
70-
if (!_compiled.IsMatch(content))
71-
{
72-
throw new Exception($"The regex didn't match.");
73-
}
74-
}
75102
}

StreamRegex.Benchmarks/Program.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using StreamRegex.Lib.DFA;
55
using StreamRegex.Lib.NFA;
66

7-
// var summary = BenchmarkRunner.Run<PerformanceVsStandard>();
7+
var summary = BenchmarkRunner.Run<PerformanceVsStandard>();
88
// NFATest();
99
void ExtensionsTest()
1010
{
+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
using System.Text;
2+
using System.Text.RegularExpressions;
3+
using BenchmarkDotNet.Attributes;
4+
using StreamRegex.Extensions;
5+
using StreamRegex.Lib.DFA;
6+
using StreamRegex.Lib.NFA;
7+
8+
namespace StreamRegex.Benchmarks;
9+
[MemoryDiagnoser]
10+
11+
// Tests checking for the string "racecar" that only occurs at the end of a very large file.
12+
public class LargeFileBenchmarks
13+
{
14+
private readonly Regex _compiled;
15+
private const string Pattern = "racecar";
16+
private Stream _stream = new MemoryStream();
17+
private const int _paddingLength = 1024 * 1024 * 100; // 100 MB
18+
private StringBuilder _testData = new StringBuilder();
19+
public LargeFileBenchmarks()
20+
{
21+
while (_testData.Length < _paddingLength)
22+
{
23+
_testData.Append(Enumerable.Repeat("a", 1024));
24+
}
25+
26+
_testData.Append(Pattern);
27+
_compiled = new Regex(Pattern, RegexOptions.Compiled);
28+
}
29+
30+
[IterationSetup]
31+
public void IterationSetup()
32+
{
33+
_stream = new MemoryStream(Encoding.UTF8.GetBytes(_testData.ToString()));
34+
}
35+
36+
[IterationCleanup]
37+
public void IterationCleanup()
38+
{
39+
_stream.Dispose();
40+
}
41+
42+
[BenchmarkCategory("Regex")]
43+
[Benchmark]
44+
public void CompiledRegex()
45+
{
46+
var content = new StreamReader(_stream).ReadToEnd();
47+
var match = _compiled.Match(content);
48+
if (!match.Success || match.Index != _paddingLength)
49+
{
50+
throw new Exception($"The regex didn't match {match.Index}.");
51+
}
52+
}
53+
54+
[BenchmarkCategory("Regex")]
55+
[Benchmark]
56+
public void RegexExtension()
57+
{
58+
var content = new StreamReader(_stream);
59+
var match = _compiled.GetFirstMatch(content);
60+
if (!match.Success || match.Index != _paddingLength)
61+
{
62+
throw new Exception($"The regex didn't match {match.Index}.");
63+
}
64+
}
65+
66+
[BenchmarkCategory("Contains")]
67+
[Benchmark(Baseline = true)]
68+
69+
public void SimpleString()
70+
{
71+
var match = new StreamReader(_stream).ReadToEnd().IndexOf("racecar");
72+
if (match != _paddingLength)
73+
{
74+
throw new Exception($"The regex didn't match {match}.");
75+
}
76+
}
77+
78+
[BenchmarkCategory("Contains")]
79+
[Benchmark]
80+
public void StringExtension()
81+
{
82+
var content = new StreamReader(_stream);
83+
var match = content.IndexOf("racecar");
84+
if (match != _paddingLength)
85+
{
86+
throw new Exception($"The regex didn't match {match}.");
87+
}
88+
}
89+
90+
91+
// [Benchmark]
92+
public void StateMachine()
93+
{
94+
var stateMachine = StateMachineFactory.CreateStateMachine(Pattern);
95+
if (stateMachine.GetFirstMatchPosition(_stream) == -1)
96+
{
97+
throw new Exception("The regex didn't match");
98+
}
99+
}
100+
101+
// [Benchmark]
102+
public void NFAStateMachine()
103+
{
104+
var stateMachine = NfaStateMachineFactory.CreateStateMachine(Pattern);
105+
var match = stateMachine.Match(_stream);
106+
if (match is null)
107+
{
108+
throw new Exception("The regex didn't match");
109+
}
110+
}
111+
}

StreamRegex.Extensions/SlidingBufferExtensions.cs

+6-4
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ public static class SlidingBufferExtensions
1010
/// <param name="comparison"></param>
1111
/// <param name="options"></param>
1212
/// <returns></returns>
13-
public static bool Contains(this Stream toMatch, string target, StringComparison comparison, SlidingBufferOptions? options = null)
13+
public static bool Contains(this Stream toMatch, string target, StringComparison? comparison = null, SlidingBufferOptions? options = null)
1414
{
15-
return new StreamReader(toMatch).IsMatch(contentChunk => contentChunk.Contains(target, comparison), options);
15+
return new StreamReader(toMatch).Contains(target, comparison, options);
1616
}
1717

1818
/// <summary>
@@ -23,9 +23,11 @@ public static bool Contains(this Stream toMatch, string target, StringComparison
2323
/// <param name="comparison"></param>
2424
/// <param name="options"></param>
2525
/// <returns></returns>
26-
public static bool Contains(this StreamReader toMatch, string target, StringComparison comparison, SlidingBufferOptions? options = null)
26+
public static bool Contains(this StreamReader toMatch, string target, StringComparison? comparison = null, SlidingBufferOptions? options = null)
2727
{
28-
return toMatch.IsMatch(contentChunk => contentChunk.Contains(target, comparison), options);
28+
return comparison is { } notNullComparison ?
29+
toMatch.IsMatch(contentChunk => contentChunk.Contains(target, notNullComparison), options) :
30+
toMatch.IsMatch(contentChunk => contentChunk.Contains(target), options);
2931
}
3032

3133
/// <summary>

StreamRegex.Extensions/SlidingBufferMatchCollection.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace StreamRegex.Extensions;
66

77
/// <summary>
8-
/// A collection holding unique <see cref="SlidingBufferMatch"/>.
8+
/// A collection holding unique <see cref="SlidingBufferMatch"/> for a single resource. The matches are Records which are deduplicated automatically.
99
/// </summary>
1010
public class SlidingBufferMatchCollection<T> : IEnumerable<T> where T : SlidingBufferMatch
1111
{
@@ -46,15 +46,15 @@ public void AddMatches(IEnumerable<T> matchCollection)
4646
}
4747

4848
/// <summary>
49-
/// Update the index position of the matches in this collection by a specific offset and return the collection.
49+
/// Update the index position of the matches in this collection by a specific offset and return the modified collection. Does not make a copy.
5050
/// </summary>
5151
/// <param name="offset">The offset to apply</param>
5252
/// <returns>This collection with the matches modified</returns>
5353
public SlidingBufferMatchCollection<T> WithOffset(long offset)
5454
{
55-
foreach (var SlidingBufferMatch in _collection)
55+
foreach (var slidingBufferMatch in _collection)
5656
{
57-
SlidingBufferMatch.Index += offset;
57+
slidingBufferMatch.Index += offset;
5858
}
5959

6060
return this;

0 commit comments

Comments
 (0)