From 3b4b93780eb25f31d0da60afcef3b214dc022411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?JasonXuDeveloper=20-=20=E5=82=91?= Date: Sun, 19 Jan 2025 12:59:53 +0800 Subject: [PATCH] release v3.0.9 - [opt] optimised code generation for user-defined dictionary types - [opt] optimised source generator performance by caching collected types (**experimental**) --- src/Nino.Generator/NinoTypeHelper.cs | 44 ++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/Nino.Generator/NinoTypeHelper.cs b/src/Nino.Generator/NinoTypeHelper.cs index 9433246..0b582a9 100644 --- a/src/Nino.Generator/NinoTypeHelper.cs +++ b/src/Nino.Generator/NinoTypeHelper.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -29,7 +30,7 @@ public static List GetPotentialCollectionTypes(this ImmutableArray< return null; }) - .Concat(NinoTypeHelper.GetAllNinoRequiredTypes(compilation)) + .Concat(GetAllNinoRequiredTypes(compilation)) .Where(s => s != null) .Select(s => s!) .Distinct(SymbolEqualityComparer.Default) @@ -43,7 +44,8 @@ public static List GetPotentialCollectionTypes(this ImmutableArray< namedTypeSymbol.Name == "ICollection" && namedTypeSymbol.TypeArguments.Length == 1); var cond = forDeserialization ? i != null //when deserializing, we want ICollection and dont care other things - : i != null && !i.IsUnmanagedType && // when serializing, we want ICollection of what we want, i.e. not unmanaged, otherwise we have a default fallback + : i != null && + !i.IsUnmanagedType && // when serializing, we want ICollection of what we want, i.e. not unmanaged, otherwise we have a default fallback i.TypeArguments.All(t => t.IsSerializableType()); if (cond) { @@ -103,21 +105,21 @@ bool IsTypeParameter(ITypeSymbol typeSymbol) .OfType() .Where(p => p.IsIndexer) .ToList(); - + //ensure there exists one public indexer that returns vType and takes only kType var validIndexers = indexers.Where(p => - p.Type.Equals(vType, SymbolEqualityComparer.Default) && p.Parameters.Length == 1 && - p.Parameters[0].Type.Equals(kType, SymbolEqualityComparer.Default)) + p.Type.Equals(vType, SymbolEqualityComparer.Default) && p.Parameters.Length == 1 && + p.Parameters[0].Type.Equals(kType, SymbolEqualityComparer.Default)) .ToList(); if (!validIndexers.Any()) return false; - + //ensure the valid indexer has public getter and setter if (validIndexers.Any(p => p.GetMethod?.DeclaredAccessibility == Accessibility.Public && p.SetMethod?.DeclaredAccessibility == Accessibility.Public)) { return true; } - + return false; } @@ -370,8 +372,14 @@ bool IsContainingTypeValid(ITypeSymbol type) .ToList(); } + private static readonly ConcurrentDictionary> AllNinoRequiredTypesCache = new(); + public static IEnumerable GetAllNinoRequiredTypes(Compilation compilation) { + if (AllNinoRequiredTypesCache.TryGetValue(compilation.GetHashCode(), out var types)) + //return a copy + return types.ToArray(); + var lst = GetAllTypes(compilation) .Where(s => s != null) .Distinct(SymbolEqualityComparer.Default) @@ -416,11 +424,14 @@ public static IEnumerable GetAllNinoRequiredTypes(Compilation compi { AddElementRecursively(typeSymbol, ret); } - - return ret.Distinct(SymbolEqualityComparer.Default) + + AllNinoRequiredTypesCache[compilation.GetHashCode()] = ret.Distinct(SymbolEqualityComparer.Default) .Where(s => s != null) .Select(s => (ITypeSymbol)s!) .ToList(); + + //return a copy + return AllNinoRequiredTypesCache[compilation.GetHashCode()].ToArray(); } private static void AddElementRecursively(ITypeSymbol symbol, List ret) @@ -450,8 +461,15 @@ private static void AddTypeArguments(INamedTypeSymbol symbol, List } } + + private static readonly ConcurrentDictionary> AllTypesCache = new(); + public static IEnumerable GetAllTypes(Compilation compilation) { + if (AllTypesCache.TryGetValue(compilation.GetHashCode(), out var types)) + //return a copy + return types.ToArray(); + var allTypes = new List(); // Add all types from the current assembly (compilation) @@ -467,13 +485,15 @@ public static IEnumerable GetAllTypes(Compilation compilation) } } - //distinct - return allTypes + AllTypesCache[compilation.GetHashCode()] = allTypes .Distinct(SymbolEqualityComparer.Default) .Where(s => s != null) .Select(s => (INamedTypeSymbol)s!) .ToList(); + + //return a copy + return AllTypesCache[compilation.GetHashCode()].ToArray(); } private static IEnumerable GetTypesInNamespace(INamespaceSymbol namespaceSymbol) @@ -583,7 +603,7 @@ public static string GetTypeModifiers(this ITypeSymbol typeSymbol) return typeKind; } - + public static bool IsPolymorphicType(this ITypeSymbol typeDecl) { var baseType = typeDecl.BaseType;