今天擴展一個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
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
00:00:00.0020176
但還是有一點點的影響,不過比起之前已經可以忽略不計了。