From f1f8bdeb09d983720b0a22aceb8e9567a0b5aaab Mon Sep 17 00:00:00 2001 From: Matt Kotsenas Date: Wed, 4 Sep 2024 14:39:14 -0700 Subject: [PATCH] Eliminate allocs in TypeConverterCache lookup path --- YamlDotNet/Helpers/DictionaryExtensions.cs | 4 ++-- .../Serialization/Utilities/TypeConverterCache.cs | 14 +++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/YamlDotNet/Helpers/DictionaryExtensions.cs b/YamlDotNet/Helpers/DictionaryExtensions.cs index f5038c91..96c9fd75 100644 --- a/YamlDotNet/Helpers/DictionaryExtensions.cs +++ b/YamlDotNet/Helpers/DictionaryExtensions.cs @@ -26,7 +26,7 @@ namespace YamlDotNet.Helpers { internal static class DictionaryExtensions { -#if NETSTANDARD2_0 || NETFRAMEWORK +#if NETSTANDARD || NETFRAMEWORK public static bool TryAdd(this System.Collections.Generic.Dictionary dictionary, T key, V value) { if (dictionary.ContainsKey(key)) @@ -39,7 +39,7 @@ public static bool TryAdd(this System.Collections.Generic.Dictionary } #endif -#if NETSTANDARD2_0 || NETFRAMEWORK +#if NETSTANDARD || NETFRAMEWORK public static TValue GetOrAdd(this ConcurrentDictionary dictionary, TKey key, Func valueFactory, TArg arg) { if (dictionary == null) { throw new ArgumentNullException(nameof(dictionary)); } diff --git a/YamlDotNet/Serialization/Utilities/TypeConverterCache.cs b/YamlDotNet/Serialization/Utilities/TypeConverterCache.cs index 683658ea..288a08d4 100644 --- a/YamlDotNet/Serialization/Utilities/TypeConverterCache.cs +++ b/YamlDotNet/Serialization/Utilities/TypeConverterCache.cs @@ -24,6 +24,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; +using YamlDotNet.Helpers; namespace YamlDotNet.Serialization.Utilities { @@ -52,12 +53,7 @@ public TypeConverterCache(IYamlTypeConverter[] typeConverters) /// if a type converter was found; otherwise. public bool TryGetConverterForType(Type type, [NotNullWhen(true)] out IYamlTypeConverter? typeConverter) { - var result = cache.GetOrAdd(type, (t) => - { - var converter = LookupTypeConverter(type); - var found = converter != null; - return (found, converter); - }); + var result = cache.GetOrAdd(type, static (t, tc) => LookupTypeConverter(t, tc), typeConverters); typeConverter = result.TypeConverter; return result.HasMatch; @@ -87,18 +83,18 @@ public IYamlTypeConverter GetConverterByType(Type converter) throw new ArgumentException($"{nameof(IYamlTypeConverter)} of type {converter.FullName} not found", nameof(converter)); } - private IYamlTypeConverter? LookupTypeConverter(Type type) + private static (bool HasMatch, IYamlTypeConverter? TypeConverter) LookupTypeConverter(Type type, IYamlTypeConverter[] typeConverters) { // Intentially avoids LINQ as this is on a hot path foreach (var typeConverter in typeConverters) { if (typeConverter.Accepts(type)) { - return typeConverter; + return (true, typeConverter); } } - return null; + return (false, null); } } }