注意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();
                }
            }));
        }

這似乎是多此一舉的無用測試,卻着實使我大吃一驚!

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);
        }

再次測試的時間如下:

00:00:00.0016531
00:00:00.0020176
 
但還是有一點點的影響,不過比起之前已經可以忽略不計了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM