Improve ForEach micro-benchmark for ImmutableArray (#1183)
authorHenrique Fernandes Baggio <henrique.baggio@outlook.com>
Fri, 27 Dec 2019 17:00:45 +0000 (14:00 -0300)
committerJan Kotas <jkotas@microsoft.com>
Fri, 27 Dec 2019 17:00:45 +0000 (09:00 -0800)
commit7ae48cff293aa71a0b4d09d57996b78ec27f2fad
tree9d4ac6d35da38172df2752d93dfe398a61fa9979
parent7012768294a103e21436864e061047e5f4925e9c
Improve ForEach micro-benchmark for ImmutableArray (#1183)

* Improve Foreach benchmark in ImmutableArray<Int32>

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/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs