AggressiveInlining
In C# programs, the JIT compiler logically determines which methods to inline. But sometimes we may know better than it does.
With AggressiveInlining
, we give the compiler a hint. We tell it that the method should be inlined. This does not guarantee inlining, but it makes is more likely.
This example benchmarks a method with no attribute, and with AggressiveInlining
. The method body contains several lines of useless code.
MethodImplOptions
AggressiveInlining
option to Method2
. This is an enum
.AggressiveInlining
), the calls required less than one nanosecond each.using System; using System.Diagnostics; using System.Runtime.CompilerServices; class Program { const int _max = 10000000; static void Main() { // ... Compile the methods. Method1(); Method2(); int sum = 0; var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { sum += Method1(); } s1.Stop(); var s2 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { sum += Method2(); } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); } static int Method1() { // ... No inlining suggestion. return "one".Length + "two".Length + "three".Length + "four".Length + "five".Length + "six".Length + "seven".Length + "eight".Length + "nine".Length + "ten".Length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] static int Method2() { // ... Aggressive inlining. return "one".Length + "two".Length + "three".Length + "four".Length + "five".Length + "six".Length + "seven".Length + "eight".Length + "nine".Length + "ten".Length; } }7.34 ns No options 0.32 ns MethodImplOptions.AggressiveInlining
For critical algorithms, using a micro-optimization on hot code is often worthwhile. But this is the uncommon case—most code needs little optimization.
AggressiveInlining
When should we apply this option? I have found that larger methods, such as the one in the example, benefit from this sort of inlining.
Method calls have a cost, but also a benefit. They require an activation record, but also reduce instruction count. Our challenge is to find the best balance between these considerations.