azure-sdk-for-net
azure-sdk-for-net copied to clipboard
Reduce memory allocation in HttpMessageSanitizer
This is a performance optimization in HttpMessageSanitizer to reduce the memory allocated in common cases.
There are three optimization techniques:
- Use
url.AsSpan(...)instead ofurl.Substring(...)to create the query part of the URL. - Defer creation of the
StringBuilderuntil/unless absolutely necessary (when there's a redacted query value) - Use a cached StringBuilder.
I added benchmarks to show the difference:
Baseline
| Method | Mean | Error | StdDev | Gen0 | Allocated |
|---|---|---|---|---|---|
| SanitizeHeader | 3.890 ns | 0.3120 ns | 0.3468 ns | - | - |
| SanitizeUrl | 8.218 ns | 0.7272 ns | 0.8375 ns | - | - |
| SanitizeUrlWithQueryNoValue | 110.411 ns | 4.3084 ns | 4.7888 ns | 0.0004 | 264 B |
| SanitizeUrlWithAllowedQuery | 137.150 ns | 7.0172 ns | 7.7996 ns | 0.0005 | 360 B |
| SanitizeUrlWithDisallowedQuery | 185.949 ns | 7.9072 ns | 9.1060 ns | 0.0007 | 464 B |
Candidate
| Method | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|
| SanitizeHeader | 4.148 ns | 0.5924 ns | 0.6822 ns | - |
| SanitizeUrl | 7.978 ns | 0.9843 ns | 1.1336 ns | - |
| SanitizeUrlWithQueryNoValue | 21.698 ns | 1.9727 ns | 2.2717 ns | - |
| SanitizeUrlWithAllowedQuery | 27.414 ns | 2.7250 ns | 3.1381 ns | - |
| SanitizeUrlWithDisallowedQuery | 84.632 ns | 5.9402 ns | 6.8407 ns | 104 B |
As you can see, we avoid memory allocations (and potential garbage collections) in common cases where there are no query parameters or where all the query parameters are allowed. In the case where we have to redact query values, the bytes allocated is one fourth of the baseline.
Thank you for your contribution @pharring! We will review the pull request and get back to you soon.
API change check
API changes are not detected in this pull request.
//cc: @JoshLove-msft, in case there's any overlap with the test proxy sanitization.
Any further comments? If not, can I get a review and sign-off?
@pharring : Give a mention when you're comfortable with things and I'll merge on your behalf.
@jsquire #sign-off
//cc: @JoshLove-msft, in case there's any overlap with the test proxy sanitization.
No this shouldn't impact anything with test recordings as logs are not part of the request/responses.