Skip to content

Instantly share code, notes, and snippets.

@redknightlois
Created September 11, 2015 17:28
Show Gist options
  • Save redknightlois/5bafa47ee9835605da26 to your computer and use it in GitHub Desktop.
Save redknightlois/5bafa47ee9835605da26 to your computer and use it in GitHub Desktop.
Benchmark for devirtualization
using BenchmarkDotNet;
using BenchmarkDotNet.Tasks;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
[BenchmarkTask(jitVersion: BenchmarkJitVersion.RyuJit, mode: BenchmarkMode.Throughput)]
[BenchmarkTask(jitVersion: BenchmarkJitVersion.LegacyJit, mode: BenchmarkMode.Throughput)]
public class Program
{
public interface ICalls
{
void Execute();
}
public class ClassCalls : ICalls
{
public static int i;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Execute()
{
i = 0;
i++;
}
}
public sealed class SealedClassCalls : ICalls
{
public static int i;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Execute()
{
i = 0;
i++;
}
}
public class Executer<T> where T : ICalls
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Execute(T instance)
{
instance.Execute();
}
}
private readonly ClassCalls _nakedClassCalls = new ClassCalls();
private readonly ICalls _nakedInterfaceCalls = new ClassCalls();
private readonly SealedClassCalls _nakedSealedCalls = new SealedClassCalls();
private readonly Executer<ClassCalls> _classCalls = new Executer<ClassCalls>();
private readonly Executer<ICalls> _interfaceCalls = new Executer<ICalls>();
private readonly Executer<SealedClassCalls> _sealedCalls = new Executer<SealedClassCalls>();
[Benchmark]
[OperationsPerInvoke(3)]
[MethodImpl(MethodImplOptions.NoInlining)]
public void UseInstanceCalls()
{
_classCalls.Execute(_nakedClassCalls);
}
[Benchmark]
[OperationsPerInvoke(3)]
[MethodImpl(MethodImplOptions.NoInlining)]
public void UseNakedInstanceCalls()
{
_nakedClassCalls.Execute();
}
[Benchmark]
[OperationsPerInvoke(3)]
[MethodImpl(MethodImplOptions.NoInlining)]
public void UseInterfaceCalls()
{
_interfaceCalls.Execute(_nakedInterfaceCalls);
}
[Benchmark]
[OperationsPerInvoke(3)]
[MethodImpl(MethodImplOptions.NoInlining)]
public void UseNakedInterfaceCalls()
{
_nakedInterfaceCalls.Execute();
}
[Benchmark]
[OperationsPerInvoke(3)]
[MethodImpl(MethodImplOptions.NoInlining)]
public void UseSealedCalls()
{
_sealedCalls.Execute(_nakedSealedCalls);
}
[Benchmark]
[OperationsPerInvoke(3)]
[MethodImpl(MethodImplOptions.NoInlining)]
public void UseNakedSealedCalls()
{
_nakedSealedCalls.Execute();
}
public void Tryout()
{
UseInstanceCalls();
UseNakedInstanceCalls();
UseSealedCalls();
UseNakedSealedCalls();
UseInterfaceCalls();
UseNakedInterfaceCalls();
}
static void Main(string[] args)
{
// new Program().Tryout();
new BenchmarkCompetitionSwitch( new[] { typeof(Program) }).Run(args);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment