注意Activator.CreateInstance兩個重載方法的性能

今天擴展一個Type的擴展方法New:性能

        public static object New(this Type type, params object[] args)
        {
            Guard.ArgumentNull(type, "type");
            return Activator.CreateInstance(type, args);
        }

而後想到了測試一下其性能,因此就和直接使用Activator.CreateInstance方法做一下比較:測試

        public void TestCreateInstance()
        {
            Console.WriteLine(TimeWatcher.Watch(() =>
                {
                    for (var i = 0; i < 10000; i++)
                    {
                        var o = Activator.CreateInstance(typeof(TestSerializeClass1));
                    }
                }));
            Console.WriteLine(TimeWatcher.Watch(() =>
            {
                for (var i = 0; i < 10000; i++)
                {
                    var o = typeof(TestSerializeClass1).New();
                }
            }));
        }

這彷佛是畫蛇添足的無用測試,卻着實使我大吃一驚!this

00:00:00.0015076
00:00:00.0104130
 
爲何發生瞭如此大的變化,不就是沒有指定第二個參數麼!!
使用Reflector查看 Activator.CreateInstance(Type type) 和  Activator.CreateInstance(Type type, params object[] args) 方法,發現它們的實現都不同,但具體慢在什麼地方,暫時尚未時間去分析。
所以,在寫公共類庫的時候,性能測試是必須的,尤爲是使用反射的狀況下,更是要注意這樣的陷阱。
 
修改後的New方法以下:
        public static object New(this Type type, params object[] args)
        {
            Guard.ArgumentNull(type, "type");
            if (args == null || args.Length == 0)
            {
                return Activator.CreateInstance(type);
            }

            return Activator.CreateInstance(type, args);
        }

再次測試的時間以下:spa

00:00:00.0016531
00:00:00.0020176
 
但仍是有一點點的影響,不過比起以前已經能夠忽略不計了。
相關文章
相關標籤/搜索