다음을 통해 공유


LateNew source

The following code is for the post "Activator.CreateInstance and beyond"

**All source code is provided as is, with no warranties intended or implied. Use at your own risk.**

Instruction

 perl sample.pl > sample.cs
csc /t:library sample.cs    
csc /o+ latenew.cs
To run: latenew sample.dll 1000 1000

sample.pl

 for $i (1..2000)
{
    $name = "C$i";
    print "public class $name { public $name() {} public $name(int i) {} public $name(string s) {} }\n";
}

latenew.cs

 using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;

class LateNew
{
    static int LOOP;
    static int TYPENUM;
    static Type[] types;

    delegate void Approach(out DateTime prepareStart, out DateTime executeStart, out DateTime finish);

    static void Measure(Approach d)
    {
        DateTime prepareStart, executeStart, finish;
        d(out prepareStart, out executeStart, out finish);
        Console.WriteLine("{0} - {1}", executeStart - prepareStart, finish - executeStart);
        GC.Collect(2);
        GC.WaitForPendingFinalizers();
    }

    static void Main(string[] args)
    {
        types = Assembly.LoadFrom(args[0]).GetTypes();
        LOOP = Int32.Parse(args[1]);
        TYPENUM = Int32.Parse(args[2]);
        if (TYPENUM > types.Length) TYPENUM = types.Length;

        Console.WriteLine("Total Type #: {0}", types.Length);
        Console.WriteLine("Used  Type #: {0}", TYPENUM);
        Console.WriteLine("Loop: {0}", LOOP);

        Measure(ParameterAndActivator);
        Measure(ParameterAndEmit);
        Measure(ParameterAndEmitAndDelegate);
        Measure(ParameterAndDynamicMethod);
        Measure(ParameterAndDynamicMethodAndDelegate);
        Measure(ParameterAndCtorInfo);

        Measure(ParameterlessAndActivator);
        Measure(ParameterlessAndEmit);
        Measure(ParameterlessAndEmitAndDelegate);
        Measure(ParameterlessAndDynamicMethod);
        Measure(ParameterlessAndDynamicMethodAndDelegate);
        Measure(ParameterlessAndCtorInfo);
    }
    public delegate object CtorInt32Delegate(int arg);
    public delegate object CtorDelegate();

    private static void ParameterAndActivator(out DateTime prepareStart, out DateTime executeStart, out DateTime finish)
    {
        prepareStart = DateTime.Now;
        executeStart = prepareStart;
        for (int i = 0; i < LOOP; i++)
            for (int j = 0; j < TYPENUM; )
                Activator.CreateInstance(types[j++], 100);
        finish = DateTime.Now;
    }
    private static void ParameterAndCtorInfo(out DateTime prepareStart, out DateTime executeStart, out DateTime finish)
    {
        prepareStart = DateTime.Now;
        Dictionary<Type, ConstructorInfo> ctors = new Dictionary<Type, ConstructorInfo>();
        foreach (Type t in types)
            ctors.Add(t, t.GetConstructor(new Type[] { typeof(int) }));
        executeStart = DateTime.Now;
        for (int i = 0; i < LOOP; i++)
            for (int j = 0; j < TYPENUM; )
                ctors[types[j++]].Invoke(new object[] { 100 });
        finish = DateTime.Now;
    }
    private static void ParameterAndDynamicMethod(out DateTime prepareStart, out DateTime executeStart, out DateTime finish)
    {
        prepareStart = DateTime.Now;
        Dictionary<Type, DynamicMethod> ctors = new Dictionary<Type, DynamicMethod>();
        foreach (Type type in types)
        {
            DynamicMethod dm = new DynamicMethod("MyCtor", type, new Type[] { typeof(int) }, typeof(LateNew).Module, true);
            ILGenerator ilgen = dm.GetILGenerator();
            ilgen.Emit(OpCodes.Nop);
            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Newobj, type.GetConstructor(new Type[] { typeof(int) }));
            ilgen.Emit(OpCodes.Ret);

            ctors.Add(type, dm);
        }
        executeStart = DateTime.Now;
        for (int i = 0; i < LOOP; i++)
            for (int j = 0; j < TYPENUM; )
                ctors[types[j++]].Invoke(null, new object[] { 100 });
        finish = DateTime.Now;
    }
    private static void ParameterAndDynamicMethodAndDelegate(out DateTime prepareStart, out DateTime executeStart, out DateTime finish)
    {
        prepareStart = DateTime.Now;
        Dictionary<Type, CtorInt32Delegate> ctors = new Dictionary<Type, CtorInt32Delegate>();
        foreach (Type type in types)
        {
            DynamicMethod dm = new DynamicMethod("MyCtor", type, new Type[] { typeof(int) }, typeof(LateNew).Module, true);
            ILGenerator ilgen = dm.GetILGenerator();
            ilgen.Emit(OpCodes.Nop);
            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Newobj, type.GetConstructor(new Type[] { typeof(int) }));
            ilgen.Emit(OpCodes.Ret);

            ctors.Add(type, (CtorInt32Delegate)dm.CreateDelegate(typeof(CtorInt32Delegate)));
        }
        executeStart = DateTime.Now;
        for (int i = 0; i < LOOP; i++)
            for (int j = 0; j < TYPENUM; )
                ctors[types[j++]](100);
        finish = DateTime.Now;
    }
    private static void ParameterAndEmit(out DateTime prepareStart, out DateTime executeStart, out DateTime finish)
    {
        prepareStart = DateTime.Now;
        AssemblyBuilder asmBldr = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("inmemory"), AssemblyBuilderAccess.Run);
        ModuleBuilder modBldr = asmBldr.DefineDynamicModule("helper");
        TypeBuilder typeBldr = modBldr.DefineType("ClassFactory");
        foreach (Type type in types)
        {
            MethodBuilder methBldr = typeBldr.DefineMethod(type.Name, MethodAttributes.Public | MethodAttributes.Static, type, new Type[] { typeof(int) });
            ILGenerator ilgen = methBldr.GetILGenerator();
            ilgen.Emit(OpCodes.Nop);
            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Newobj, type.GetConstructor(new Type[] { typeof(int) }));
            ilgen.Emit(OpCodes.Ret);

        }
        Type baked = typeBldr.CreateType();
        Dictionary<Type, MethodInfo> ctors = new Dictionary<Type, MethodInfo>();
        foreach (Type type in types)
            ctors.Add(type, baked.GetMethod(type.Name));

        executeStart = DateTime.Now;
        for (int i = 0; i < LOOP; i++)
            for (int j = 0; j < TYPENUM; )
                ctors[types[j++]].Invoke(null, new object[] { 100 });
        finish = DateTime.Now;
    }
    private static void ParameterAndEmitAndDelegate(out DateTime prepareStart, out DateTime executeStart, out DateTime finish)
    {
        prepareStart = DateTime.Now;
        AssemblyBuilder asmBldr = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("inmemory"), AssemblyBuilderAccess.Run);
        ModuleBuilder modBldr = asmBldr.DefineDynamicModule("helper");
        TypeBuilder typeBldr = modBldr.DefineType("ClassFactory");
        foreach (Type type in types)
        {
            MethodBuilder methBldr = typeBldr.DefineMethod(type.Name, MethodAttributes.Public | MethodAttributes.Static, type, new Type[] { typeof(int) });
            ILGenerator ilgen = methBldr.GetILGenerator();
            ilgen.Emit(OpCodes.Nop);
            ilgen.Emit(OpCodes.Ldarg_0);
            ilgen.Emit(OpCodes.Newobj, type.GetConstructor(new Type[] { typeof(int) }));
            ilgen.Emit(OpCodes.Ret);

        }
        Type baked = typeBldr.CreateType();
        Dictionary<Type, CtorInt32Delegate> ctors = new Dictionary<Type, CtorInt32Delegate>();
        foreach (Type type in types)
            ctors.Add(type, (CtorInt32Delegate)Delegate.CreateDelegate(typeof(CtorInt32Delegate), baked.GetMethod(type.Name)));
        executeStart = DateTime.Now;
        for (int i = 0; i < LOOP; i++)
            for (int j = 0; j < TYPENUM; )
                ctors[types[j++]](100);
        finish = DateTime.Now;
    }

    private static void ParameterlessAndActivator(out DateTime prepareStart, out DateTime executeStart, out DateTime finish)
    {
        prepareStart = DateTime.Now;
        executeStart = prepareStart;
        for (int i = 0; i < LOOP; i++)
            for (int j = 0; j < TYPENUM; )
                Activator.CreateInstance(types[j++]);
        finish = DateTime.Now;
    }
    private static void ParameterlessAndCtorInfo(out DateTime prepareStart, out DateTime executeStart, out DateTime finish)
    {
        prepareStart = DateTime.Now;
        Dictionary<Type, ConstructorInfo> ctors = new Dictionary<Type, ConstructorInfo>();
        foreach (Type t in types)
            ctors.Add(t, t.GetConstructor(Type.EmptyTypes));

        executeStart = DateTime.Now;
        for (int i = 0; i < LOOP; i++)
            for (int j = 0; j < TYPENUM; )
                ctors[types[j++]].Invoke(null);
        finish = DateTime.Now;
    }
    private static void ParameterlessAndDynamicMethod(out DateTime prepareStart, out DateTime executeStart, out DateTime finish)
    {
        prepareStart = DateTime.Now;
        Dictionary<Type, DynamicMethod> ctors = new Dictionary<Type, DynamicMethod>();
        foreach (Type type in types)
        {
            DynamicMethod dm = new DynamicMethod("MyCtor", type, Type.EmptyTypes, typeof(LateNew).Module, true);
            ILGenerator ilgen = dm.GetILGenerator();
            ilgen.Emit(OpCodes.Nop);
            ilgen.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));
            ilgen.Emit(OpCodes.Ret);

            ctors.Add(type, dm);
        }

        executeStart = DateTime.Now;
        for (int i = 0; i < LOOP; i++)
            for (int j = 0; j < TYPENUM; )
                ctors[types[j++]].Invoke(null, null);
        finish = DateTime.Now;
    }
    private static void ParameterlessAndDynamicMethodAndDelegate(out DateTime prepareStart, out DateTime executeStart, out DateTime finish)
    {
        prepareStart = DateTime.Now;
        Dictionary<Type, CtorDelegate> ctors = new Dictionary<Type, CtorDelegate>();
        foreach (Type type in types)
        {
            DynamicMethod dm = new DynamicMethod("MyCtor", type, Type.EmptyTypes, typeof(LateNew).Module, true);
            ILGenerator ilgen = dm.GetILGenerator();
            ilgen.Emit(OpCodes.Nop);
            ilgen.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));
            ilgen.Emit(OpCodes.Ret);

            ctors.Add(type, (CtorDelegate)dm.CreateDelegate(typeof(CtorDelegate)));
        }

        executeStart = DateTime.Now;
        for (int i = 0; i < LOOP; i++)
            for (int j = 0; j < TYPENUM; )
                ctors[types[j++]]();
        finish = DateTime.Now;
    }
    private static void ParameterlessAndEmit(out DateTime prepareStart, out DateTime executeStart, out DateTime finish)
    {
        prepareStart = DateTime.Now;
        AssemblyBuilder asmBldr = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("inmemory"), AssemblyBuilderAccess.Run);
        ModuleBuilder modBldr = asmBldr.DefineDynamicModule("helper");
        TypeBuilder typeBldr = modBldr.DefineType("ClassFactory");

        foreach (Type type in types)
        {
            MethodBuilder methBldr = typeBldr.DefineMethod(type.Name, MethodAttributes.Public | MethodAttributes.Static, type, Type.EmptyTypes);
            ILGenerator ilgen = methBldr.GetILGenerator();
            ilgen.Emit(OpCodes.Nop);
            ilgen.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));
            ilgen.Emit(OpCodes.Ret);

        }
        Type baked = typeBldr.CreateType();

        Dictionary<Type, MethodInfo> ctors = new Dictionary<Type, MethodInfo>();
        foreach (Type type in types)
            ctors.Add(type, baked.GetMethod(type.Name));

        executeStart = DateTime.Now;
        for (int i = 0; i < LOOP; i++)
            for (int j = 0; j < TYPENUM; )
                ctors[types[j++]].Invoke(null, null);
        finish = DateTime.Now;
    }
    private static void ParameterlessAndEmitAndDelegate(out DateTime prepareStart, out DateTime executeStart, out DateTime finish)
    {
        prepareStart = DateTime.Now;
        AssemblyBuilder asmBldr = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("inmemory"), AssemblyBuilderAccess.Run);
        ModuleBuilder modBldr = asmBldr.DefineDynamicModule("helper");
        TypeBuilder typeBldr = modBldr.DefineType("ClassFactory");

        foreach (Type type in types)
        {
            MethodBuilder methBldr = typeBldr.DefineMethod(type.Name, MethodAttributes.Public | MethodAttributes.Static, type, Type.EmptyTypes);
            ILGenerator ilgen = methBldr.GetILGenerator();
            ilgen.Emit(OpCodes.Nop);
            ilgen.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes));
            ilgen.Emit(OpCodes.Ret);

        }
        Type baked = typeBldr.CreateType();

        Dictionary<Type, CtorDelegate> ctors = new Dictionary<Type, CtorDelegate>();
        foreach (Type type in types)
            ctors.Add(type, (CtorDelegate)Delegate.CreateDelegate(typeof(CtorDelegate), baked.GetMethod(type.Name)));

        executeStart = DateTime.Now;
        for (int i = 0; i < LOOP; i++)
            for (int j = 0; j < TYPENUM; )
                ctors[types[j++]]();
        finish = DateTime.Now;
    }
}