Activator.CreateInstance


Expression.Lambdaでコンパイル後使いまわすのが優位。
リフレクション系のメソッドアクセスやプロパティアクセスも同様。
型だけ決めて動作系はすべて同一にするパターンで有効

Activator.CreateInstance:81
Expression.Lambda:20

using System;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;

namespace ConsoleApplication2
{
  class Program
  {
    static void Main(string[] args)
    {
      var loopcount = 1000000;

      var stopWatch = new Stopwatch();
      stopWatch.Start();

      var t = typeof(Class1);

      for (int i = 0; i < loopcount; i++)
      {
        var ins = Activator.CreateInstance(t);
      }

      stopWatch.Stop();
      Console.WriteLine("Activator.CreateInstance:{0}", stopWatch.ElapsedMilliseconds);
      stopWatch.Restart();

      var func = GetCreateInstanceFunc(t, null);
      for (int i = 0; i < loopcount; i++)
      {
        var ins = func(null);
      }

      stopWatch.Stop();
      Console.WriteLine("Expression.Lambda:{0}", stopWatch.ElapsedMilliseconds);
      stopWatch.Restart();
      
    }//end method

    public static Func<object[], object> GetCreateInstanceFunc(Type input, object[] args)
    {
      System.Reflection.ConstructorInfo constructor = null;
      if (args == null)
      {
        constructor = input.GetConstructor(Type.EmptyTypes);
      }
      else
      {
        var types = args.Select(p => p.GetType());
        constructor = input.GetConstructor(types.ToArray());
      }//end if

      var paraminfo = constructor.GetParameters();
      var paramex = Expression.Parameter(typeof(object[]), "args");

      var argex = new Expression[paraminfo.Length];
      for (int i = 0; i < paraminfo.Length; i++)
      {
        var index = Expression.Constant(i);
        var paramType = paraminfo[i].ParameterType;
        var accessor = Expression.ArrayIndex(paramex, index);
        var cast = Expression.Convert(accessor, paramType);
        argex[i] = cast;
      }

      var newex = Expression.New(constructor, argex);

      var lambda = Expression.Lambda(typeof(Func<object[], object>), newex, paramex);
      var result = (Func<object[], object>)lambda.Compile();
      return result;
    }//end method

    
  }//end class
}//end namespace
カテゴリー: 開発 タグ: パーマリンク