using System.Linq.Expressions;
using System.Diagnostics;
public int[] AddInts(int[] a, int[] b) {
int[] output = new int[a.Length + b.Length];
Array.Copy(a,0,output,0,a.Length);
Array.Copy(b,0,output,a.Length,b.Length);
public int[] GetArr2(object arg) {
public static Delegate MethodToInstanceDelegate(object target, MethodInfo method) {
ParameterInfo[] methodParams = method.GetParameters();
Type[] methodParamTypes = new Type[methodParams.Length + 1];
for(int j = 0; j < methodParams.Length; j += 1) {
methodParamTypes[j] = methodParams[j].ParameterType;
methodParamTypes[methodParamTypes.Length-1] = method.ReturnType;
Type delegateType = Expression.GetDelegateType(methodParamTypes);
return Delegate.CreateDelegate(delegateType,target, method);
public static Delegate MethodToInstanceDelegate(object target, string methodName) {
MethodInfo method = target.GetType().GetMethod(methodName);
return MethodToInstanceDelegate(target,method);
public static Delegate MethodToDelegate(Type parentType, MethodInfo method) {
ParameterInfo[] methodParams = method.GetParameters();
Type[] methodParamTypes = new Type[methodParams.Length + 2];
methodParamTypes[0] = parentType;
for(int j = 0; j < methodParams.Length; j += 1) {
methodParamTypes[j+1] = methodParams[j].ParameterType;
methodParamTypes[methodParamTypes.Length-1] = method.ReturnType;
Type delegateType = Expression.GetDelegateType(methodParamTypes);
return Delegate.CreateDelegate(delegateType, null, method);
public static Delegate MethodToDelegate(Type parentType, string methodName) {
MethodInfo method = parentType.GetMethod(methodName);
return MethodToDelegate(parentType,method);
public static Func<object> CastGeneric(object func) {
return func as Func<object>;
public static Func<object,object> CastGeneric2(object func) {
return func as Func<object,object>;
public static Func<object,object,object> CastGeneric3(object func) {
return func as Func<object,object,object>;
public static Func<object,object,object, object> CastGeneric4(object func) {
return func as Func<object,object,object,object>;
public static void Main()
Delegate del = MethodToInstanceDelegate(dem,"GetArr2");
Delegate openDel = MethodToDelegate(typeof(Demo),"GetArr2");
Func<int[]> func = () => {return new int[10];};
Console.WriteLine(del.ToString());
Stopwatch watch = new Stopwatch();
for(int i = 0; i < iters; i++) {
object ob = dem.GetArr2(null);
Console.WriteLine("Throw away");
Console.WriteLine("Baseline" );
watch = Stopwatch.StartNew();
for(int i = 0; i < iters; i++) {
object ob = dem.GetArr2(null);
baseline = (int)watch.ElapsedTicks;
Console.WriteLine(baseline);
Console.WriteLine("\nOpen NoCast" );
watch = Stopwatch.StartNew();
for(int i = 0; i < iters; i++) {
object ob = ((Func<Demo,object,int[]>)openDel)(dem, null);
Console.WriteLine(watch.ElapsedTicks + " tcks " + (float)watch.ElapsedTicks / (float)baseline);
Console.WriteLine("\nOpen Cast" );
watch = Stopwatch.StartNew();
for(int i = 0; i < iters; i++) {
object ob = ((Func<Demo,object,object>)openDel)(dem, null);
Console.WriteLine(watch.ElapsedTicks + " tcks " + (float)watch.ElapsedTicks / (float)baseline);
Console.WriteLine("\nClosed Cast" );
watch = Stopwatch.StartNew();
for(int i = 0; i < iters; i++) {
object ob = ((Func<object,object>)del)(null);
Console.WriteLine(watch.ElapsedTicks + " tcks " + (float)watch.ElapsedTicks / (float)baseline);
Console.WriteLine("\nClosed DynamicInvoke" );
object[] argBuff = new object[1];
watch = Stopwatch.StartNew();
for(int i = 0; i < iters; i++) {
object ob = del.DynamicInvoke(argBuff);
Console.WriteLine(watch.ElapsedTicks + " tcks " + (float)watch.ElapsedTicks / (float)baseline);