Skip to content

Commit

Permalink
Merge pull request aaubry#969 from MattKotsenas/refactor/type-cache-a…
Browse files Browse the repository at this point in the history
…llocs

Eliminate allocs in TypeConverterCache lookup path

+semver:fix
  • Loading branch information
EdwardCooke authored Sep 5, 2024
2 parents 440d607 + f1f8bde commit 32ecda7
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 11 deletions.
4 changes: 2 additions & 2 deletions YamlDotNet/Helpers/DictionaryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace YamlDotNet.Helpers
{
internal static class DictionaryExtensions
{
#if NETSTANDARD2_0 || NETFRAMEWORK
#if NETSTANDARD || NETFRAMEWORK
public static bool TryAdd<T, V>(this System.Collections.Generic.Dictionary<T, V> dictionary, T key, V value)
{
if (dictionary.ContainsKey(key))
Expand All @@ -39,7 +39,7 @@ public static bool TryAdd<T, V>(this System.Collections.Generic.Dictionary<T, V>
}
#endif

#if NETSTANDARD2_0 || NETFRAMEWORK
#if NETSTANDARD || NETFRAMEWORK
public static TValue GetOrAdd<TKey, TValue, TArg>(this ConcurrentDictionary<TKey, TValue> dictionary, TKey key, Func<TKey, TArg, TValue> valueFactory, TArg arg)
{
if (dictionary == null) { throw new ArgumentNullException(nameof(dictionary)); }
Expand Down
14 changes: 5 additions & 9 deletions YamlDotNet/Serialization/Utilities/TypeConverterCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using YamlDotNet.Helpers;

namespace YamlDotNet.Serialization.Utilities
{
Expand Down Expand Up @@ -52,12 +53,7 @@ public TypeConverterCache(IYamlTypeConverter[] typeConverters)
/// <returns><see langword="true"/> if a type converter was found; <see langword="false"/> otherwise.</returns>
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;
Expand Down Expand Up @@ -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);
}
}
}

0 comments on commit 32ecda7

Please sign in to comment.