From 6c66879c92207b5a2638ec43d04a858ebeff8fd8 Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Tue, 18 Jun 2024 09:23:04 +1000 Subject: [PATCH] Optimize the `+=` operation for a collection when it's an object array (#23901) --- .../engine/parser/Compiler.cs | 3 +++ .../engine/runtime/Binding/Binders.cs | 8 ++++++++ .../engine/runtime/Operations/ArrayOps.cs | 9 +++++++++ 3 files changed, 20 insertions(+) diff --git a/src/System.Management.Automation/engine/parser/Compiler.cs b/src/System.Management.Automation/engine/parser/Compiler.cs index 68e5091b57..30528f9958 100644 --- a/src/System.Management.Automation/engine/parser/Compiler.cs +++ b/src/System.Management.Automation/engine/parser/Compiler.cs @@ -39,6 +39,9 @@ namespace System.Management.Automation.Language internal static readonly MethodInfo ObjectList_ToArray = typeof(List).GetMethod(nameof(List.ToArray), Type.EmptyTypes); + internal static readonly MethodInfo ArrayOps_AddObject = + typeof(ArrayOps).GetMethod(nameof(ArrayOps.AddObjectArray), StaticFlags); + internal static readonly MethodInfo ArrayOps_GetMDArrayValue = typeof(ArrayOps).GetMethod(nameof(ArrayOps.GetMDArrayValue), StaticFlags); diff --git a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs index 3e3ec3fbca..8d403b8e2f 100644 --- a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs +++ b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs @@ -2717,6 +2717,14 @@ namespace System.Management.Automation.Language lhsEnumerator.Expression.Cast(typeof(IEnumerator)), rhsEnumerator.Expression.Cast(typeof(IEnumerator))); } + else if (target.Value is object[] targetArray) + { + // Adding 1 item to an object[] + // This is an optimisation over the default EnumerableOps_AddObject. + call = Expression.Call(CachedReflectionInfo.ArrayOps_AddObject, + target.Expression.Cast(typeof(object[])), + arg.Expression.Cast(typeof(object))); + } else { // Adding 1 item to a list diff --git a/src/System.Management.Automation/engine/runtime/Operations/ArrayOps.cs b/src/System.Management.Automation/engine/runtime/Operations/ArrayOps.cs index fa4c2c2b56..4fd68cdd20 100644 --- a/src/System.Management.Automation/engine/runtime/Operations/ArrayOps.cs +++ b/src/System.Management.Automation/engine/runtime/Operations/ArrayOps.cs @@ -12,6 +12,15 @@ namespace System.Management.Automation { internal static class ArrayOps { + internal static object AddObjectArray(object[] lhs, object rhs) + { + int newIdx = lhs.Length; + Array.Resize(ref lhs, newIdx + 1); + lhs[newIdx] = rhs; + + return lhs; + } + internal static object[] SlicingIndex(object target, object[] indexes, Func indexer) { var result = new object[indexes.Length];