Skip to content

Commit f278bb2

Browse files
committed
Remove redundant lookup (and loading) in _runtimeAssemblyNames ir RT.classForName
1 parent 443c591 commit f278bb2

File tree

1 file changed

+80
-54
lines changed

1 file changed

+80
-54
lines changed

Clojure/Clojure/Lib/RT.cs

Lines changed: 80 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2826,20 +2826,44 @@ public static Type classForName(string p)
28262826
return classForName(p, CurrentNSVar.deref() as Namespace, true);
28272827
}
28282828

2829+
public static int NumDuplicates { get; set; } = 0;
2830+
public static int NumDirects { get; set; } = 0;
2831+
public static int NumLoadedAssemblyFinds { get; set; } = 0;
2832+
public static int NumRuntimeAssemblyLoads { get; set; } = 0;
2833+
public static int NumRuntimeAssemblyFinds { get; set; } = 0;
2834+
public static int NumLoadedAssemblyFinds2 { get; set; } = 0;
2835+
public static int NumParsing { get; set; } = 0;
2836+
public static int NumFails { get; set; } = 0;
2837+
2838+
public static void ClassForNameReport()
2839+
{
2840+
Console.WriteLine($"NumDuplicates: {NumDuplicates}");
2841+
Console.WriteLine($"NumDirects: {NumDirects}");
2842+
Console.WriteLine($"NumLoadedAssemblyFinds: {NumLoadedAssemblyFinds}");
2843+
Console.WriteLine($"NumRuntimeAssemblyLoads: {NumRuntimeAssemblyLoads}");
2844+
Console.WriteLine($"NumRuntimeAssemblyFinds: {NumRuntimeAssemblyFinds}");
2845+
Console.WriteLine($"NumLoadedAssemblyFinds2: {NumLoadedAssemblyFinds2}");
2846+
Console.WriteLine($"NumParsing: {NumParsing}");
2847+
Console.WriteLine($"NumFails: {NumFails}");
2848+
2849+
}
2850+
28292851
internal static Type classForName(string p, Namespace ns, bool canCallClrTypeSpec)
28302852
{
28312853
// First, check for types generated during the current compilation session.
28322854

28332855
Type t = Compiler.FindDuplicateType(p);
28342856
if (t != null)
28352857
{
2858+
NumDuplicates++;
28362859
return t;
28372860
}
28382861

28392862
// Try using Type.GetType which can find types with assembly-qualified names.
28402863
t = Type.GetType(p, false);
28412864
if (t != null && (t.IsPublic || t.IsNestedPublic))
28422865
{
2866+
NumDirects++;
28432867
return t;
28442868
}
28452869

@@ -2853,13 +2877,12 @@ internal static Type classForName(string p, Namespace ns, bool canCallClrTypeSpe
28532877
Type t1 = assy.GetType(p, false);
28542878
if (t1 != null && (t1.IsPublic || t1.IsNestedPublic))
28552879
{
2880+
NumLoadedAssemblyFinds++;
28562881
return t1;
28572882
}
28582883
}
28592884

28602885
// Try to load from runtime libraries if we have DependencyContext.
2861-
var runtimeAssemblyNames = _runtimeAssemblyNames.Value;
2862-
if (runtimeAssemblyNames.Count > 0)
28632886
{
28642887
// Split the type name to identify the namespace and simple name.
28652888
string namespaceName = null;
@@ -2871,69 +2894,65 @@ internal static Type classForName(string p, Namespace ns, bool canCallClrTypeSpe
28712894
typeName = p.Substring(lastDot + 1);
28722895
}
28732896

2874-
// Try to find and load the assembly that might contain this type.
2875-
foreach (var assemblyName in runtimeAssemblyNames)
2897+
if (!string.IsNullOrEmpty(namespaceName))
28762898
{
2877-
// Skip if this assembly is already loaded.
2878-
if (loadedAssemblies.Any(a => a.GetName().Name == assemblyName.Name))
2879-
{
2880-
continue;
2881-
}
28822899

2883-
// Try common patterns for framework assemblies.
2884-
if (namespaceName != null)
2900+
var runtimeAssemblyNames = _runtimeAssemblyNames.Value;
2901+
if (runtimeAssemblyNames.Count > 0)
28852902
{
2886-
// Check if the assembly name matches the namespace pattern.
2887-
if (assemblyName.Name.StartsWith("System") && namespaceName.StartsWith("System"))
2903+
2904+
// Try to find and load the assembly that might contain this type.
2905+
foreach (var assemblyName in runtimeAssemblyNames)
28882906
{
2889-
try
2907+
// Skip if this assembly is already loaded.
2908+
if (loadedAssemblies.Any(a => a.GetName().Name == assemblyName.Name))
28902909
{
2891-
var assy = Assembly.Load(assemblyName);
2892-
var type = assy.GetType(p, false);
2893-
if (type != null && (type.IsPublic || type.IsNestedPublic))
2894-
{
2895-
return type;
2896-
}
2910+
continue;
28972911
}
2898-
catch { }
2899-
}
2900-
// Also try if the namespace directly matches the assembly name.
2901-
else if (assemblyName.Name.Equals(namespaceName, StringComparison.OrdinalIgnoreCase))
2902-
{
2903-
try
2912+
2913+
// try if the namespace directly matches the assembly name.
2914+
if (assemblyName.Name.Equals(namespaceName, StringComparison.OrdinalIgnoreCase))
29042915
{
2905-
var assy = Assembly.Load(assemblyName);
2906-
var type = assy.GetType(p, false);
2907-
if (type != null && (type.IsPublic || type.IsNestedPublic))
2916+
try
29082917
{
2909-
return type;
2918+
NumRuntimeAssemblyLoads++;
2919+
var assy = Assembly.Load(assemblyName);
2920+
var type = assy.GetType(p, false);
2921+
if (type != null && (type.IsPublic || type.IsNestedPublic))
2922+
{
2923+
NumRuntimeAssemblyFinds++;
2924+
return type;
2925+
}
29102926
}
2927+
catch { }
29112928
}
2912-
catch { }
2929+
29132930
}
29142931
}
29152932
}
29162933
}
29172934

2918-
// Re-check loaded assemblies (some might have been loaded during the search).
2919-
loadedAssemblies = domain.GetAssemblies();
2920-
foreach (Assembly assy in loadedAssemblies)
2921-
{
2922-
Type t1 = assy.GetType(p, false);
2923-
if (t1 != null && (t1.IsPublic || t1.IsNestedPublic))
2924-
{
2925-
return t1;
2926-
}
2927-
}
2935+
//// Re-check loaded assemblies (some might have been loaded during the search).
2936+
//loadedAssemblies = domain.GetAssemblies();
2937+
//foreach (Assembly assy in loadedAssemblies)
2938+
//{
2939+
// Type t1 = assy.GetType(p, false);
2940+
// if (t1 != null && (t1.IsPublic || t1.IsNestedPublic))
2941+
// {
2942+
// NumLoadedAssemblyFinds2++;
2943+
// return t1;
2944+
// }
2945+
//}
29282946

29292947
// Search by simple type name (slow path).
2930-
List<Type> candidateTypes = [];
2931-
foreach (Assembly assy1 in loadedAssemblies)
2948+
// At some point this became a no-op unless running on Mono, so I restricted it to that.
2949+
if (IsRunningOnMono)
29322950
{
2933-
Type t1 = null;
2934-
2935-
if (IsRunningOnMono)
2951+
List<Type> candidateTypes = [];
2952+
foreach (Assembly assy1 in loadedAssemblies)
29362953
{
2954+
Type t1 = null;
2955+
29372956
if (!assy1.IsDynamic)
29382957
{
29392958
try
@@ -2951,19 +2970,20 @@ internal static Type classForName(string p, Namespace ns, bool canCallClrTypeSpe
29512970
{
29522971
}
29532972
}
2973+
2974+
2975+
if (t1 != null && !candidateTypes.Contains(t1))
2976+
{
2977+
candidateTypes.Add(t1);
2978+
}
29542979
}
29552980

2956-
if (t1 != null && !candidateTypes.Contains(t1))
2981+
if (candidateTypes.Count == 1)
29572982
{
2958-
candidateTypes.Add(t1);
2983+
return candidateTypes[0];
29592984
}
29602985
}
29612986

2962-
if (candidateTypes.Count == 1)
2963-
{
2964-
return candidateTypes[0];
2965-
}
2966-
29672987
//// Handle generic types and array types.
29682988
//if (p.IndexOfAny(_triggerTypeChars) != -1)
29692989
//{
@@ -2972,7 +2992,12 @@ internal static Type classForName(string p, Namespace ns, bool canCallClrTypeSpe
29722992

29732993
if (canCallClrTypeSpec)
29742994
{
2975-
return ClrTypeSpec.GetTypeFromName(p, ns);
2995+
var t1 = ClrTypeSpec.GetTypeFromName(p, ns);
2996+
if (t1 is not null)
2997+
{
2998+
NumParsing++;
2999+
return t1;
3000+
}
29763001

29773002
}
29783003
//// Handle generic types and array types.
@@ -2981,6 +3006,7 @@ internal static Type classForName(string p, Namespace ns, bool canCallClrTypeSpe
29813006
// return ClrTypeSpec.GetTypeFromName(p);
29823007
//}
29833008

3009+
NumFails++;
29843010
return null;
29853011
}
29863012

0 commit comments

Comments
 (0)