-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Removing unsafe parts of Decode method in QueryStringEnumerable #56630
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Fixing IterationCount related data consistency issues in QueryCollectionBenchmarks
source.Replace(buffer, '+', ' '); | ||
var success = Uri.TryUnescapeDataString(buffer, buffer, out var unescapedLength); | ||
Debug.Assert(success); | ||
return buffer.AsMemory(0, unescapedLength); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
The difference here to commit Removing unsafe parts of Decode method in QueryStringEnumerable is that this implementation keeps a reference to the 'buffer' array that might be larger to the return value with the
AsMemory()
call. On the other hand, this implementation avoids an extrastring
allocation as shown on the perf measurement's Encoded line - and as well faster in that scenario. -
I think
Uri.TryUnescapeDataString
should not return false, despite this comment. The unescape level used byTryUnescapeDataString
method seems to avoid the 'rare' case. As an alternative the code could branch based on the result ofTryUnescapeDataString
, and in case of afalse
value invoke theUri.UnescapeDataString
method as a fallback.
Or as another alternative, go with the implementation from the previous commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, TryUnescapeDataString shouldn't be able to return false in our case.
https://source.dot.net/#System.Private.Uri/System/UriExt.cs,648
source.Replace(buffer, '+', ' '); | ||
var success = Uri.TryUnescapeDataString(buffer, buffer, out var unescapedLength); | ||
Debug.Assert(success); | ||
return buffer.AsMemory(0, unescapedLength); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, TryUnescapeDataString shouldn't be able to return false in our case.
https://source.dot.net/#System.Private.Uri/System/UriExt.cs,648
Thanks @ladeak! 1/Unknown unsafe usages gone 😄 |
Removing unsafe parts of Decode method in QueryStringEnumerable
Description
string.Create
by stack allocating a buffer when the input is smaller than 256 chars and using the ROS overload ofUri.UnescapeDataString
. While this reduced some allocations overall, it cost a performance penalty (ie. the Single case below is executing in the ~74 ns range instead of ~67ns) on my machine.Performance
Just to confirm there is no perf degradation.
BEFORE:
BenchmarkDotNet=v0.13.0, OS=Windows 10.0.22631
12th Gen Intel Core i7-1255U, 1 CPU, 12 logical and 10 physical cores
.NET SDK=9.0.100-preview.6.24316.4
[Host] : .NET 9.0.0 (9.0.24.32008), X64 RyuJIT
Job-PTTTFA : .NET 9.0.0 (9.0.24.30702), X64 RyuJIT
Server=True Toolchain=.NET Core 9.0 RunStrategy=Throughput
Measurement 1:
Measurement 2:
AFTER:
Measurement 1:
Measurement 2:
Part of: #56534