File tree 5 files changed +117
-15
lines changed
VerbalExpressionsUnitTests
5 files changed +117
-15
lines changed Original file line number Diff line number Diff line change
1
+ using System ;
2
+ using System . Text . RegularExpressions ;
3
+
4
+ namespace CSharpVerbalExpressions
5
+ {
6
+ public sealed class RegexCache
7
+ {
8
+ private bool hasValue ;
9
+ private Key key ;
10
+ private Regex regex ;
11
+
12
+ private class Key
13
+ {
14
+ public Key ( string pattern , RegexOptions options )
15
+ {
16
+ this . Pattern = pattern ;
17
+ this . Options = options ;
18
+ }
19
+
20
+ public string Pattern { get ; private set ; }
21
+ public RegexOptions Options { get ; private set ; }
22
+
23
+ public override bool Equals ( object obj )
24
+ {
25
+ var key = obj as Key ;
26
+ return key != null &&
27
+ key . Pattern == this . Pattern &&
28
+ key . Options == this . Options ;
29
+ }
30
+
31
+ public override int GetHashCode ( )
32
+ {
33
+ return this . Pattern . GetHashCode ( ) ^ this . Options . GetHashCode ( ) ;
34
+ }
35
+ }
36
+
37
+ /// <summary>
38
+ /// Gets the already cached value for a key, or calculates the value and stores it.
39
+ /// </summary>
40
+ /// <param name="pattern">The pattern used to create the regular expression.</param>
41
+ /// <param name="options">The options for regex.</param>
42
+ /// <returns>The calculated or cached value.</returns>
43
+ public Regex Get ( string pattern , RegexOptions options )
44
+ {
45
+ if ( pattern == null ) throw new ArgumentNullException ( "pattern" ) ;
46
+
47
+ lock ( this )
48
+ {
49
+ var current = new Key ( pattern , options ) ;
50
+ if ( this . hasValue && current . Equals ( this . key ) )
51
+ {
52
+ return this . regex ;
53
+ }
54
+
55
+ this . regex = new Regex ( pattern , options ) ;
56
+ this . key = current ;
57
+ this . hasValue = true ;
58
+ return this . regex ;
59
+ }
60
+ }
61
+ }
62
+ }
Original file line number Diff line number Diff line change @@ -36,11 +36,13 @@ public static VerbalExpressions DefaultExpression
36
36
37
37
#region Private Members
38
38
39
+ private readonly RegexCache regexCache = new RegexCache ( ) ;
40
+
39
41
private string _prefixes = "" ;
40
42
private string _source = "" ;
41
43
private string _suffixes = "" ;
42
44
private RegexOptions _modifiers = RegexOptions . Multiline ;
43
-
45
+
44
46
#endregion Private Members
45
47
46
48
#region Private Properties
@@ -52,23 +54,11 @@ private string RegexString
52
54
53
55
private Regex PatternRegex
54
56
{
55
- get { return new Regex ( this . RegexString , _modifiers ) ; }
57
+ get { return regexCache . Get ( this . RegexString , _modifiers ) ; }
56
58
}
57
59
58
60
#endregion Private Properties
59
-
60
- #region Constructors
61
-
62
- public VerbalExpressions ( )
63
- {
64
- }
65
-
66
- static VerbalExpressions ( )
67
- {
68
- }
69
-
70
- #endregion Constructors
71
-
61
+
72
62
#region Public Methods
73
63
74
64
#region Helpers
Original file line number Diff line number Diff line change 70
70
</ItemGroup >
71
71
<ItemGroup >
72
72
<Compile Include =" CommonRegex.cs" />
73
+ <Compile Include =" RegexCache.cs" />
73
74
<Compile Include =" VerbalExpressions.cs" />
74
75
<Compile Include =" Properties\AssemblyInfo.cs" />
75
76
</ItemGroup >
Original file line number Diff line number Diff line change
1
+ using System ;
2
+ using System . Diagnostics ;
3
+ using System . Text . RegularExpressions ;
4
+ using CSharpVerbalExpressions ;
5
+ using NUnit . Framework ;
6
+
7
+ namespace VerbalExpressionsUnitTests
8
+ {
9
+ [ TestFixture ]
10
+ public class PerformanceTests
11
+ {
12
+
13
+ [ Test ]
14
+ public void VerbalExpression_Is_Not_Slower_Than_Direct_Use_Of_Regex ( )
15
+ {
16
+ const string someUrl = "https://www.google.com" ;
17
+
18
+ var verbEx = VerbalExpressions . DefaultExpression
19
+ . StartOfLine ( )
20
+ . Then ( "http" )
21
+ . Maybe ( "s" )
22
+ . Then ( "://" )
23
+ . Maybe ( "www." )
24
+ . AnythingBut ( " " )
25
+ . EndOfLine ( ) ;
26
+
27
+ var regex = new Regex ( @"^http(s)?://([\w-]+.)+[\w-]+(/[\w- ./?%&=])?$" ) ;
28
+
29
+ var timeVerbEx = MeasureCallDuration ( ( ) => verbEx . IsMatch ( someUrl ) ) ;
30
+ var timeRegex = MeasureCallDuration ( ( ) => regex . IsMatch ( someUrl ) ) ;
31
+
32
+ Assert . That ( timeVerbEx - timeRegex , Is . LessThan ( TimeSpan . FromSeconds ( 0.1 ) ) ) ;
33
+ }
34
+
35
+ private static TimeSpan MeasureCallDuration ( Action action )
36
+ {
37
+ var sw = Stopwatch . StartNew ( ) ;
38
+
39
+ for ( var i = 0 ; i < 10000 ; i ++ )
40
+ {
41
+ action ( ) ;
42
+ }
43
+
44
+ sw . Stop ( ) ;
45
+ return sw . Elapsed ;
46
+ }
47
+ }
48
+ }
Original file line number Diff line number Diff line change 43
43
<Compile Include =" AddModifierTests.cs" />
44
44
<Compile Include =" AddTests.cs" />
45
45
<Compile Include =" CaptureTests.cs" />
46
+ <Compile Include =" PerformanceTests.cs" />
46
47
<Compile Include =" RepeatPreviousTest.cs" />
47
48
<Compile Include =" EndOfLineTests.cs" />
48
49
<Compile Include =" MaybeTests.cs" />
You can’t perform that action at this time.
0 commit comments