From 7ae48cff293aa71a0b4d09d57996b78ec27f2fad Mon Sep 17 00:00:00 2001 From: Henrique Fernandes Baggio Date: Fri, 27 Dec 2019 14:00:45 -0300 Subject: [PATCH] Improve ForEach micro-benchmark for ImmutableArray (#1183) * Improve Foreach benchmark in ImmutableArray Analysis of the generated ASM code vs the same benchmark for Array shows that the GetEnumerator call is not being inlined (the loop itself is). In the case of the ValueType ImmutableArray.GetEnumerator method, there's a call to ThrowNullRefIfNotInitialized for validation. By adding MethodImplAttribute(MethodImplOptions.AggressiveInlining) to both methods, we are able to force the JIT to inline the call and get similar results in the benchmark. Looking at the hardware counters collected in the benchmark, there are less CacheMisses and BranchMispredictions/Op when the inlining happens. Unfortunately, the same fix didn't seem to work for the other overloads of GetEnumerator, for the explicit generic implementation. That still needs more investigation. * AggressiveInline in ThrowNullRefIfNotInitialized isn't needed to inline GetEnumerator --- .../src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs index c134fe0..4fa82d9 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs @@ -8,6 +8,7 @@ using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Globalization; using System.Linq; +using System.Runtime.CompilerServices; using System.Runtime.Versioning; namespace System.Collections.Immutable @@ -283,6 +284,7 @@ namespace System.Collections.Immutable /// /// An enumerator. [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Enumerator GetEnumerator() { var self = this; -- 2.7.4