-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Cache parameter writer lookups #24536
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
84390b7
to
b1acbbb
Compare
public WritersForType(Type targetType) | ||
{ | ||
WritersByName = new Dictionary<string, IPropertySetter>(StringComparer.OrdinalIgnoreCase); | ||
_underlyingWriters = new Dictionary<string, IPropertySetter>(StringComparer.OrdinalIgnoreCase); | ||
_writerCache = new ConcurrentDictionary<StringObjectIdentityKey, IPropertySetter?>(); |
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.
There's a ReferenceEqualityComparer<T>
type in 5.0 you could use. You can avoid create the type type. Basically,
_writerCache = new ConcurrentDictionary<StringObjectIdentityKey, IPropertySetter?>(); | |
_writerCache = new ConcurrentDictionary<string, IPropertySetter?>(ReferenceEqualityComparer<string>.Instance); |
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.
Great, thanks for the tip! I switched over to this and not only does it save code, but it reduces the instruction count by another 1% on the ComplexTable benchmark (probably because it no longer has to call the constructor or field setter for my custom type).
@@ -41,7 +42,7 @@ public static void SetProperties(in ParameterView parameters, object target) | |||
foreach (var parameter in parameters) | |||
{ | |||
var parameterName = parameter.Name; | |||
if (!writers.WritersByName.TryGetValue(parameterName, out var writer)) | |||
if (!writers.TryGetValue(parameterName, out var writer)) |
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.
One additional optimization we could make is to stash the the WritesForType
as an internal property on ComponentBase
and avoid the dictionary lookup there.
if (target is ComponentBase component)
{
component.Writer ?? = new WritersForType(targetType);
_writer = component.Writer;
}
else
{
// old code
}
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.
Thanks for the suggestion. Since this didn't show up in the profile traces as a hot path, I'd prefer not to add an optimization for it.
I guess that doing the lookup for this dictionary is relatively cheap because component.GetHashCode()
is much cheaper than computing a string hash.
b1acbbb
to
a08a27d
Compare
See description at #24466.
This improves the ComplexTable benchmark by about 7.3% (though the op count improves by 17%).