-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
System.Net.WebProxy takes a list of strings for Uris that should bypass the proxy.
This list of strings is compiled into a list of Regex by the method UpdateRegexList
This method is called in the constructor and in the BypassList property setter.
This is normal.
However, this method is also called in IsMatchInBypassList, which is called by IsBypassed
This feels wrong. I don't see why it needs to systematically refresh the regex list in this call.
It re-allocates the array and all the regex, for no reason (as far as I can see anyway).
Regression?
This behavior seems to be copy-pasted from the .Net Framework code, which is also wrong.
https://referencesource.microsoft.com/#system/net/system/Net/webproxy.cs
Analysis
The following code shows a significant difference between the proxy1 et proxy2 execution time
(typically ~230ms vs ~2100ms)
Since the call to IsBypassed returns true for the first regex, the length of the Bypasslist should not matter.
Uri uri = new Uri("https://a.com/");
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
bool r1 = true;
System.Net.WebProxy proxy1 = new System.Net.WebProxy("http://localhost:9999", true, new string[] { "a" });
sw.Restart();
for (int i = 0; i < 100000; i++) {
r1 &= proxy1.IsBypassed(uri);
}
sw.Stop();
Console.WriteLine($"Proxy1 : {sw.ElapsedMilliseconds}ms ({r1})");
bool r2 = true;
System.Net.WebProxy proxy2 = new System.Net.WebProxy("http://localhost:9999", true, new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" });
sw.Restart();
for (int i = 0; i < 100000; i++) {
r2 &= proxy2.IsBypassed(uri);
}
sw.Stop();
Console.WriteLine($"Proxy2 : {sw.ElapsedMilliseconds}ms ({r2})");