-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Improve perf of CredentialCache.GetCredential #103714
Conversation
Tagging subscribers to this area: @dotnet/ncl |
/benchmark micro aspnet-perf-lin libs --variable filter=*GetCredential_Uri |
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System;
using System.Collections.Generic;
using System.Net;
public class CredentialCacheTests
{
private const string UriPrefix = "http://name";
private const string HostPrefix = "name";
private const int Port = 80;
private const string AuthenticationType = "authType";
private static readonly NetworkCredential s_credential = new NetworkCredential();
private readonly Dictionary<(int uriCount, int hostPortCount), CredentialCache> _caches = new()
{
{ (0, 0), CreateCredentialCache(0, 0) },
{ (0, 10), CreateCredentialCache(0, 10) },
{ (10, 0), CreateCredentialCache(10, 0) },
{ (10, 10), CreateCredentialCache(10, 10) }
};
[Benchmark]
[Arguments("http://notfound", 0)]
[Arguments("http://notfound", 10)]
[Arguments("http://name5", 10)]
public NetworkCredential GetCredential_Uri(string uriString, int uriCount)
{
CredentialCache cc = _caches[(uriCount: uriCount, hostPortCount: 0)];
return cc.GetCredential(new Uri(uriString), AuthenticationType);
}
private static CredentialCache CreateCredentialCache(int uriCount, int hostPortCount)
{
var cc = new CredentialCache();
for (int i = 0; i < uriCount; i++)
{
Uri uri = new Uri(UriPrefix + i.ToString());
cc.Add(uri, AuthenticationType, s_credential);
}
for (int i = 0; i < hostPortCount; i++)
{
string host = HostPrefix + i.ToString();
cc.Add(host, Port, AuthenticationType, s_credential);
}
return cc;
}
} |
Benchmark results on Intel
|
I took a look at why we regressed the one scenario, and it seems that that particular benchmark is measuring a corner case. I locally editted the benchmarks so that the creds in the cache on the same host, but different prefix (
Since the regressed scenario is when we are querying a completely different host, I think the regression is not a big problem. |
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System;
using System.Collections.Generic;
using System.Net;
public class CredentialCacheTests
{
private const string UriPrefix = "http://name/prefix";
private const string HostPrefix = "name";
private const int Port = 80;
private const string AuthenticationType = "authType";
private static readonly NetworkCredential s_credential = new NetworkCredential();
private readonly Dictionary<(int uriCount, int hostPortCount), CredentialCache> _caches =
new Dictionary<(int uriCount, int hostPortCount), CredentialCache>
{
{ (0, 0), CreateCredentialCache(0, 0) },
{ (0, 10), CreateCredentialCache(0, 10) },
{ (10, 0), CreateCredentialCache(10, 0) },
{ (10, 10), CreateCredentialCache(10, 10) }
};
[Benchmark]
[Arguments("http://notfound", 0)]
[Arguments("http://differentHost", 10)]
[Arguments("http://name/prefix5/path", 10)]
[Arguments("http://name/differentPrefix/path", 10)]
[Arguments("http://name/diff/path", 10)]
public NetworkCredential GetCredential_Uri(string uriString, int uriCount)
{
CredentialCache cc = _caches[(uriCount: uriCount, hostPortCount: 0)];
return cc.GetCredential(new Uri(uriString), AuthenticationType);
}
private static CredentialCache CreateCredentialCache(int uriCount, int hostPortCount)
{
var cc = new CredentialCache();
for (int i = 0; i < uriCount; i++)
{
Uri uri = new Uri(UriPrefix + i.ToString() + "/");
cc.Add(uri, AuthenticationType, s_credential);
}
for (int i = 0; i < hostPortCount; i++)
{
string host = HostPrefix + i.ToString();
cc.Add(host, Port, AuthenticationType, s_credential);
}
return cc;
}
} |
Benchmark results on Intel
|
@dotnet/ncl Can I get a review? |
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.
LGTM. This can still be noise compared to actual TLS.
Fixes #101991.
Fixes #102281.
Not sure what introduced the original regression, but we can save some time by first checking if candidate credential can have longer prefix match before we start comparing auth schemes and uri, and we can stop early if we find exact match.