using System;
using System.Reflection;
using System.Timers;
namespace CallBenchmark
{
delegate void SNPCall();
delegate void SPCall(int i, int j, int k);
delegate void INPCall();
delegate void IPCall(int i, int j, int k);
class CallBenchmark
{
static int count;
static bool done;
public CallBenchmark()
{
}
public static void StaticDirectCallWithoutParams()
{
++count;
}
public static void StaticDirectCallWithParams(int i, int j, int k)
{
++count;
}
public void InstanceDirectCallWithoutParams()
{
++count;
}
public void InstanceDirectCallWithParams(int i, int j, int k)
{
++count;
}
public static void StaticDelegateWithoutParams()
{
++count;
}
public static void StaticDelegateWithParams(int i, int j, int k)
{
++count;
}
public void InstanceDelegateWithoutParams()
{
++count;
}
public void InstanceDelegateWithParams(int i, int j, int k)
{
++count;
}
public static void StaticInvokeWithoutParams()
{
++count;
}
public static void StaticInvokeWithParams(int i, int j, int k)
{
++count;
}
public void InstanceInvokeWithoutParams()
{
++count;
}
public void InstanceInvokeWithParams(int i, int j, int k)
{
++count;
}
static void Main(string[] args)
{
CallBenchmark cb=new CallBenchmark();
SNPCall snpCall=new SNPCall(StaticDelegateWithoutParams);
SPCall spCall=new SPCall(StaticDelegateWithParams);
INPCall inpCall=new INPCall(cb.InstanceDelegateWithoutParams);
IPCall ipCall=new IPCall(cb.InstanceDelegateWithParams);
MethodInfo snpMI=GetMethodInfo("CallBenchmark.exe/CallBenchmark.CallBenchmark/StaticInvokeWithoutParams");
MethodInfo spMI=GetMethodInfo("CallBenchmark.exe/CallBenchmark.CallBenchmark/StaticInvokeWithParams");
MethodInfo inpMI=GetMethodInfo("CallBenchmark.exe/CallBenchmark.CallBenchmark/InstanceInvokeWithoutParams");
MethodInfo ipMI=GetMethodInfo("CallBenchmark.exe/CallBenchmark.CallBenchmark/InstanceInvokeWithParams");
object[] parms=new Object[] {1, 2, 3};
int sampleSize=20; // # of samples
int timerInterval=200; // in ms
int[] benchmarks=new int[12];
string[] benchmarkName=new string[12]
{
"Static Direct Call Without Params",
"Static Direct Call With Params",
"Instance Direct Call Without Params",
"Instance Direct Call With Params",
"\nStatic Delegate Call Without Params",
"Static Delegate Call With Params",
"Instance Delegate Call Without Params",
"Instance Delegate Call With Params",
"\nStatic Reflection Invoke Call Without Params",
"Static Reflection Invoke Call With Params",
"Instance Reflection Invoke Call Without Params",
"Instance Reflection Invoke Call With Params",
};
for (int i=0; i<benchmarks.Length; i++)
{
benchmarks[i]=0;
}
Timer timer=new Timer(timerInterval);
timer.AutoReset=false;
timer.Stop();
timer.Elapsed+=new ElapsedEventHandler(OnTimerEvent);
int q=sampleSize;
while (q > 0)
{
Console.WriteLine("Pass # "+(sampleSize+1-q).ToString());
// ***************** Direct Calls
int n=0;
count=0;
done=false;
timer.Start();
while (!done)
{
StaticDirectCallWithoutParams();
}
benchmarks[n]+=count;
++n;
count=0;
done=false;
timer.Start();
while (!done)
{
StaticDirectCallWithParams(1, 2, 3);
}
benchmarks[n]+=count;
++n;
count=0;
done=false;
timer.Start();
while (!done)
{
cb.InstanceDirectCallWithoutParams();
}
benchmarks[n]+=count;
++n;
count=0;
done=false;
timer.Start();
while (!done)
{
cb.InstanceDirectCallWithParams(1, 2, 3);
}
benchmarks[n]+=count;
// ***************** Delegate Calls
++n;
count=0;
done=false;
timer.Start();
while (!done)
{
snpCall();
}
benchmarks[n]+=count;
++n;
count=0;
done=false;
timer.Start();
while (!done)
{
spCall(1, 2, 3);
}
benchmarks[n]+=count;
++n;
count=0;
done=false;
timer.Start();
while (!done)
{
inpCall();
}
benchmarks[n]+=count;
++n;
count=0;
done=false;
timer.Start();
while (!done)
{
ipCall(1, 2, 3);
}
benchmarks[n]+=count;
// ***************** Reflection Invoke Calls
++n;
count=0;
done=false;
timer.Start();
while (!done)
{
snpMI.Invoke(null, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Static, null, null, null);
}
benchmarks[n]+=count;
++n;
count=0;
done=false;
timer.Start();
while (!done)
{
spMI.Invoke(null, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Static, null, parms, null);
}
benchmarks[n]+=count;
++n;
count=0;
done=false;
timer.Start();
while (!done)
{
inpMI.Invoke(cb, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Static, null, null, null);
}
benchmarks[n]+=count;
++n;
count=0;
done=false;
timer.Start();
while (!done)
{
ipMI.Invoke(cb, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Static, null, parms, null);
}
benchmarks[n]+=count;
--q;
}
Console.WriteLine("Sample size = "+sampleSize.ToString());
Console.WriteLine("Timer interval = "+timerInterval.ToString()+" ms");
Console.WriteLine();
for (int i=0; i<benchmarks.Length; i++)
{
benchmarks[i]/=(sampleSize-2);
Console.WriteLine(benchmarkName[i]+": "+benchmarks[i].ToString());
}
}
static void OnTimerEvent(object src, ElapsedEventArgs e)
{
done=true;
}
/// <summary>
/// Returns a MethodInfo object with the parsed reflect string.
/// </summary>
/// <param name="reflection">A reflection method name, in the format "assembly/namespace.class/method".</param>
static public MethodInfo GetMethodInfo(string reflection)
{
MethodInfo mi=null;
string[] info=reflection.Split(new char[] {'/'});
Assembly mainAssembly=Assembly.LoadFrom(info[0]);
Type type=mainAssembly.GetType(info[1]);
mi=type.GetMethod(info[2]);
return mi;
}
}
}