KEMBAR78
Use stackalloc char&byte arrays for decoding Url values in HttpUtiliy.ParseQueryString by TrayanZapryanov · Pull Request #102745 · dotnet/runtime · GitHub
Skip to content

Conversation

@TrayanZapryanov
Copy link
Contributor

  1. Convert UrlDecoder to ref struct
  2. If Url is less than 256 characters, do no allocate char&byte arrays
  3. Replace substring operation with Span

@ghost ghost added the area-System.Net label May 28, 2024
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label May 28, 2024
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

@TrayanZapryanov
Copy link
Contributor Author

TrayanZapryanov commented May 28, 2024

Benchmark:

[MemoryDiagnoser]
public class HttpUtilityBenchmarks
{
	private static string UnicodeStr
		=> new string(new[] { '\u304a', '\u75b2', '\u308c', '\u69d8', '\u3067', '\u3059' });
	private static string EncodedUnicodeStr => HttpUtility.UrlEncode(UnicodeStr) + "=" + HttpUtility.UrlEncode(UnicodeStr);

	[Benchmark(Baseline = true)]
	public NameValueCollection ParseQueryString() => HttpUtility.ParseQueryString("https://portal.azure.com/#@testgroup.onmicrosoft.com/dashboard/arm/subscriptions/111111-abac-4067-81ba-5ae054d891b5/" +
	                                                                                "resourcegroups/dashboards/providers/microsoft.portal/dashboards/3456268-8630-60f7-aaac-eca38aca231");

	[Benchmark]
	public NameValueCollection ParseQueryString_Mix() => HttpUtility.ParseQueryString("ReturnUrl=http%3a%2f%2flocalhost%2flogin%2fauthenticate%3fReturnUrl%3dhttp%3a%2f%2flocalhost%2fsecured_area%26__provider__%3dgoogle");

	[Benchmark]
	public NameValueCollection ParseQueryString_Unicode() => HttpUtility.ParseQueryString(EncodedUnicodeStr);
}

Results:
Machine:
BenchmarkDotNet v0.13.12, Windows 11 (10.0.22631.3593/23H2/2023Update/SunValley3)
11th Gen Intel Core i9-11900K 3.50GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK 9.0.100-preview.4.24267.66
[Host] : .NET 8.0.5 (8.0.524.21615), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI
DefaultJob : .NET 8.0.5 (8.0.524.21615), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI

Before:

Method Mean Error StdDev Ratio RatioSD Gen0 Gen1 Allocated Alloc Ratio
ParseQueryString 516.0 ns 7.83 ns 6.94 ns 1.00 0.00 0.1955 - 1.6 KB 1.00
ParseQueryString_Mix 429.1 ns 5.26 ns 4.92 ns 0.83 0.01 0.1931 0.0005 1.58 KB 0.99
ParseQueryString_Unicode 691.2 ns 10.41 ns 9.74 ns 1.34 0.03 0.2689 - 2.2 KB 1.38

PR:

Method Mean Error StdDev Ratio RatioSD Gen0 Allocated Alloc Ratio
ParseQueryString 489.3 ns 4.92 ns 4.36 ns 1.00 0.00 0.1059 888 B 1.00
ParseQueryString_Mix 338.7 ns 2.76 ns 2.45 ns 0.69 0.01 0.0820 688 B 0.77
ParseQueryString_Unicode 656.1 ns 7.01 ns 6.22 ns 1.34 0.02 0.1717 1440 B 1.62

Copy link
Member

@MihaZupan MihaZupan left a comment

Choose a reason for hiding this comment

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

This is one weird class.
Thanks for taking care of these low-hanging fruit

@MihaZupan MihaZupan merged commit 49c10ed into dotnet:main May 29, 2024
@TrayanZapryanov TrayanZapryanov deleted the optimize_url_decoder branch May 29, 2024 19:11
Ruihan-Yin pushed a commit to Ruihan-Yin/runtime that referenced this pull request May 30, 2024
@MihaZupan MihaZupan added this to the 9.0.0 milestone May 31, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Jul 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Net community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants