MethodImplOptions.AggressiveInlining

The JIT compiler logically determines which methods to inline. But sometimes we know better than it does. With AggressiveInlining, we give the compiler a hint. We tell it that the method should be inlined. Actually, the only hint we give the compiler is to ignore the size restriction on the method or the property you want to inline. Using this attribute does not guarantee that the method will be inlined. There are 1000 and 1 reasons why it cannot be (being virtual for one thing)

Example

This example benchmarks a method with no attribute, and with AggressiveInlining. The method body contains several lines of useless code. This makes the method large in bytes, so the JIT compiler may decide not to inline it.

And: We apply the MethodImplOptions.AggressiveInlining option to Method2. It is an enum.

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"));
        Console.Read();
    }
 
    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;
    }
}

Output

7.34 ns No options
0.32 ns MethodImplOptions.AggressiveInlining

We see that with no options, the method calls required seven nanoseconds each. But with inlining specified (with AggressiveInlining), the calls required less than one nanosecond each.

Tip 1: Consider for a moment all the things you could do with those seven nanoseconds.

Tip 2: If you are scheduling your life based on nanoseconds, please consider reducing your coffee intake.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: