Skip to content

Conversation

@paulomorgado
Copy link
Contributor

Performance Improvements in SIP Authorization Digest Parsing

This PR introduces significant performance and memory optimizations to the ParseAuthorisationDigest method by leveraging Span<T> and eliminating unnecessary string allocations and regular expressions.

Key Improvements

1. Elimination of Regular Expression Operations

  • Removed multiple Regex.Match calls that were being performed for each header field comparison
  • These regex operations were computationally expensive and created unnecessary overhead
  • Replaced with simple case-insensitive comparisons using Equals with StringComparison.OrdinalIgnoreCase

2. Memory Usage Optimization

  • Replaced string operations with ReadOnlySpan<T> to avoid string allocations
  • Eliminated string splitting which was creating new string arrays
  • Removed intermediate string allocations in the parsing loop
  • Uses Span<T> slicing operations instead of String.Substring()

3. More Efficient Header Parsing

  • Implemented manual parsing using spans instead of string.Split()
  • Processes the input sequentially without creating intermediate collections
  • Better handling of whitespace using Trim() on spans

4. Cross-Platform Optimizations

  • Added conditional compilation for different .NET versions to use optimal APIs
  • Specialized handling for .NET Core 2.1+ and .NET 6.0+
  • Falls back to string-based operations on older frameworks while maintaining functionality

Performance Impact

  • Reduces heap allocations significantly by avoiding string creations
  • Eliminates regex compilation and matching overhead
  • More efficient memory usage through stack-based operations with spans
  • Faster parsing of authorization headers, especially for high-throughput scenarios

Testing Notes

This change maintains the exact same functionality while improving performance. All existing tests should pass without modification.

Resolves issues related to:

  • High memory allocation in authorization header parsing
  • Performance bottlenecks from regular expression usage
  • Unnecessary string object creation

{
//authRequest.Algorithm = headerValue;

#if NETCOREAPP6_0_OR_GREATER
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this preprocessor define correct? It's not lsied on https://learn.microsoft.com/en-us/dotnet/standard/frameworks#preprocessor-symbols.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right and that's a nasty bug hidden under there.

Are the - valid anywhere, or are there specific strings that should be accepted? I was looking at this and thinking a dictionary would be a better fit than parsing modified text.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The '-' are only being replaced because they can't be used in C# enums. It's safe to do so for the AUTH_ALGORITHM_KEY values. If the algorithm is not in the enum it means it's not recognised and the digest won't be able to be verified/generated any way,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than MD5 and SHA256 what other values are to be expected? SHA-256?

I wouldn't expect -M-D-5- to be valid. Is it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MD5
SHA-256
SHA-512 (not wired up, although would be trivial)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is SHA256 a valid value? Is it case insensitive?

…cs` to use `ReadOnlySpan<char>` for improved performance and memory efficiency. Simplified header field handling by replacing regular expressions and string arrays with spans and slices. Expanded unit tests in `SIPAuthorisationDigestUnitTest.cs` to cover various scenarios, including basic, full, malformed, and case-insensitive headers, as well as nonce counts and QOP values.
@sipFan
Copy link
Contributor

sipFan commented May 29, 2025

This looks like a good optimization effort! Would you be able to share any benchmark data or profiling results that illustrate the performance gains? Seeing the before-and-after numbers would be really helpful, as I’m always keen to learn more about identifying and resolving performance bottlenecks in SIP processing. I'm also curious how the regex would perform if they were to be made source generated.

@paulomorgado
Copy link
Contributor Author

@sipFan,

This looks like a good optimization effort! Would you be able to share any benchmark data or profiling results that illustrate the performance gains? Seeing the before-and-after numbers would be really helpful, as I’m always keen to learn more about identifying and resolving performance bottlenecks in SIP processing. I'm also curious how the regex would perform if they were to be made source generated.

Sure! I've applied well known and established practices, but I can provide a benchmark. Can you provide example authorisationRequests for a significant benchmark?

Sometimes these things only shine up in production with other components in the same process. But after a few years, you learn to spot them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants