rksoftware

Visual Studio とか C# とかが好きです

class のインスタンス化の計測

C# でクラスのインスタンス化にはいくつか方法があります。
少し気になって

  • (基準として) 普通に new して
  • Factory メソッドで (メソッド内部で new して)
  • Activator で
  • リフレクションでコンストラクタで

インスタンス化して時間を計ってみました。

■ 結果

Constructor - 9
Factory     - 11
Activator   - 47
Reflection  - 125

環境によって結果は変わるはずですが、未知のクラスをインスタンス化するなどの場合、Factory メソッドでインスタンス化できるようにするのが一番期待できそうです。

.NET Core 3.1.200
Mac OS X

■ コード

    class Program
    {
        static void Main(string[] args)
        {
            int loop = 1000000;
            var sw1 = new Stopwatch();
            var sw2 = new Stopwatch();
            var sw3 = new Stopwatch();
            var sw4 = new Stopwatch();
            {
                sw1.Start();
                for (int i = 0; i < loop; ++i) new Add();
                sw1.Stop();
            }
            {
                IFactory creater = new Factory();
                sw2.Start();
                for (int i = 0; i < loop; ++i) creater.Create();
                sw2.Stop();
            }
            {
                var type = typeof(Add);
                sw3.Start();
                for (int i = 0; i < loop; ++i) Activator.CreateInstance(type);
                sw3.Stop();
            }
            {
                var type = typeof(Add);
                var construcor = type.GetConstructor(Type.EmptyTypes);
                sw4.Start();
                for (int i = 0; i < loop; ++i) construcor.Invoke(null);
                sw4.Stop();
            }

            Console.WriteLine($"Constructor - {sw1.ElapsedMilliseconds}");
            Console.WriteLine($"Factory     - {sw2.ElapsedMilliseconds}");
            Console.WriteLine($"Activator   - {sw3.ElapsedMilliseconds}");
            Console.WriteLine($"Reflection  - {sw4.ElapsedMilliseconds}");
        }
    }

    public interface IFactory
    {
        IAdd Create();
    }

    public class Factory : IFactory
    {
        public IAdd Create() => new Add();
    }

    public interface IAdd
    {
    }

    public class Add : IAdd
    {
    }