Skip to content

Commit

Permalink
perf: use code generation to unroll pattern match per country (SWIFT …
Browse files Browse the repository at this point in the history
…only) (#192)

* fix: expose SwiftPattern in DEBUG, to allow code generator access to it. Exposing internals to TemporaryT4Assembly no longer works, as the temporary assembly has a new name each run (TemporaryT4Assembly_<guid>).
* feat: use unrolled pattern match, generated specifically per country.
* fix: avoid having to tokenize the pattern during validation (warmup).
  • Loading branch information
skwasjer authored Jan 20, 2024
1 parent ddaedaa commit 7888b36
Show file tree
Hide file tree
Showing 6 changed files with 4,168 additions and 735 deletions.
3 changes: 0 additions & 3 deletions src/IbanNet/Properties/AssemblyInfoAttributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,5 @@

[assembly: InternalsVisibleTo("IbanNet.Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
#if DEBUG
[assembly: InternalsVisibleTo("TemporaryT4Assembly")]
#endif
[assembly: NeutralResourcesLanguage("en")]
[assembly: CLSCompliant(true)]
8 changes: 4 additions & 4 deletions src/IbanNet/Registry/Patterns/Pattern.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public IReadOnlyList<PatternToken> Tokens
/// <summary>
/// Gets whether or not the pattern is of fixed length.
/// </summary>
public bool IsFixedLength
public virtual bool IsFixedLength
{
get
{
Expand All @@ -76,7 +76,7 @@ public bool IsFixedLength
/// <summary>
/// Gets the maximum length of this pattern.
/// </summary>
public int MaxLength
public virtual int MaxLength
{
get
{
Expand All @@ -96,10 +96,10 @@ public override string ToString()
}

#if USE_SPANS
internal bool IsMatch(ReadOnlySpan<char> value, [NotNullWhen(false)] out int? errorPos)
internal virtual bool IsMatch(ReadOnlySpan<char> value, [NotNullWhen(false)] out int? errorPos)
{
#else
internal bool IsMatch(string value, [NotNullWhen(false)] out int? errorPos)
internal virtual bool IsMatch(string value, [NotNullWhen(false)] out int? errorPos)
{
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (value is null)
Expand Down
42 changes: 40 additions & 2 deletions src/IbanNet/Registry/Swift/SwiftPattern.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,59 @@

namespace IbanNet.Registry.Swift;

internal class SwiftPattern : Pattern
/// <inheritdoc />
#if DEBUG
public
#else
internal
#endif
class SwiftPattern : Pattern
{
private static readonly SwiftPatternTokenizer Tokenizer = new();
private string? _pattern;
private readonly int? _maxLength;
private readonly bool? _isFixedLength;

/// <inheritdoc />
public SwiftPattern(string pattern) : base(pattern, Tokenizer)
{
_pattern = pattern;
}

internal SwiftPattern(IEnumerable<PatternToken> tokens) : base(tokens)
{
}

/// <inheritdoc />
internal SwiftPattern(string pattern, int maxLength, bool isFixedLength)
: this(pattern)
{
_maxLength = maxLength;
_isFixedLength = isFixedLength;
}

/// <inheritdoc />
public override bool IsFixedLength
{
get
{
return _isFixedLength ?? base.IsFixedLength;
}
}

/// <inheritdoc />
public override int MaxLength
{
get
{
return _maxLength ?? base.MaxLength;
}
}

/// <inheritdoc />
public override string ToString()
{
return string.Join("", Tokens.Select(t =>
return _pattern ??= string.Join("", Tokens.Select(t =>
{
if (t.Value is not null)
{
Expand Down
Loading

0 comments on commit 7888b36

Please sign in to comment.