diff --git a/src/UiPath.Workflow.Runtime/ActivityUtilities.cs b/src/UiPath.Workflow.Runtime/ActivityUtilities.cs index 40bf4219..5c7cc7eb 100644 --- a/src/UiPath.Workflow.Runtime/ActivityUtilities.cs +++ b/src/UiPath.Workflow.Runtime/ActivityUtilities.cs @@ -10,6 +10,8 @@ namespace System.Activities; using Expressions; using Internals; using Runtime; +using System.Collections.Concurrent; +using System.Runtime.CompilerServices; using Validation; internal static class ActivityUtilities @@ -47,6 +49,8 @@ internal static class ActivityUtilities private static readonly Type outArgumentOfObjectType = typeof(OutArgument); private static readonly Type inOutArgumentOfObjectType = typeof(InOutArgument); private static PropertyChangedEventArgs propertyChangedEventArgs; + + private static readonly ConcurrentDictionary argumentTypeCache = new(); // Can't delay create this one because we use object.ReferenceEquals on it in WorkflowInstance private static readonly ReadOnlyDictionary emptyParameters = new(new Dictionary(0)); @@ -97,6 +101,19 @@ public static bool IsInScope(ActivityInstance potentialChild, ActivityInstance s public static bool IsCompletedState(ActivityInstanceState state) => state != ActivityInstanceState.Executing; + private readonly struct ArgumentTypeInfo + { + public readonly ArgumentDirection Direction; + public readonly Type ArgumentType; + + public ArgumentTypeInfo(ArgumentDirection direction, Type argumentType) + { + Direction = direction; + ArgumentType = argumentType; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetArgumentDirectionAndType(Type propertyType, out ArgumentDirection direction, out Type argumentType) { direction = ArgumentDirection.In; // default to In @@ -104,24 +121,34 @@ public static bool TryGetArgumentDirectionAndType(Type propertyType, out Argumen if (propertyType.IsGenericType) { + if (argumentTypeCache.TryGetValue(propertyType, out ArgumentTypeInfo info)) + { + direction = info.Direction; + argumentType = info.ArgumentType; + return true; + } + argumentType = propertyType.GetGenericArguments()[0]; Type genericType = propertyType.GetGenericTypeDefinition(); if (genericType == inArgumentGenericType) { + argumentTypeCache.TryAdd(propertyType, new ArgumentTypeInfo(direction, argumentType)); return true; } if (genericType == outArgumentGenericType) { direction = ArgumentDirection.Out; + argumentTypeCache.TryAdd(propertyType, new ArgumentTypeInfo(direction, argumentType)); return true; } if (genericType == inOutArgumentGenericType) { direction = ArgumentDirection.InOut; + argumentTypeCache.TryAdd(propertyType, new ArgumentTypeInfo(direction, argumentType)); return true; } } diff --git a/src/UiPath.Workflow.Runtime/AssemblyInfo.cs b/src/UiPath.Workflow.Runtime/AssemblyInfo.cs index 86237715..42a60e36 100644 --- a/src/UiPath.Workflow.Runtime/AssemblyInfo.cs +++ b/src/UiPath.Workflow.Runtime/AssemblyInfo.cs @@ -28,4 +28,5 @@ [assembly: InternalsVisibleTo("UiPath.Workflow")] [assembly: InternalsVisibleTo("TestCases.Workflows")] [assembly: InternalsVisibleTo("TestCases.Runtime")] +[assembly: InternalsVisibleTo("CoreWf.Benchmarks")] [assembly: InternalsVisibleTo("Perf.AssemblyReference.Benchmarks")]