[Reflection] Fields, Properties SetValue performance benchmark test
今天突然想做一下 映射的效能benchrmark, 重點不在於能不能用, 而是要知道在各式量壓下, 會有如何的反應時間.
註: 每台電腦的效能不同必然會有不同的反應時間, 以下是筆者的Notebook測出的數據 ( .NET 4.0 )
代碼
1: class Data
2: {
3: public double _Value { get; set; }
4:
5: public double _ValField;
6: }
1: public void LoopTest(long count)
2: {
3: Console.WriteLine("----- loop count : " + count + " -----");
4: Data d = new Data();
5: long start = DateTime.Now.Ticks;
6: for (long i = 0; i < count; ++i) {
7: d._Value = i;
8: }
9: Console.WriteLine("Class(p) : {0:D}", new TimeSpan(DateTime.Now.Ticks - start).Milliseconds);
10: PropertyInfo property = typeof(Data).GetProperty("_Value");
11: start = DateTime.Now.Ticks;
12: for (long i = 0; i < count; ++i) {
13: property.SetValue(d, i, null);
14: }
15: Console.WriteLine("Reflect(p) : {0:D}", new TimeSpan(DateTime.Now.Ticks - start).Milliseconds);
16:
17: start = DateTime.Now.Ticks;
18: for (long i = 0; i < count; ++i)
19: {
20: d._ValField = i;
21: }
22: Console.WriteLine("Class(f) : {0:D}", new TimeSpan(DateTime.Now.Ticks - start).Milliseconds);
23:
24: FieldInfo field = typeof(Data).GetField("_ValField");
25: start = DateTime.Now.Ticks;
26: for (long i = 0; i < count; ++i)
27: {
28: field.SetValueDirect(__makeref(d), i);
29: }
30: Console.WriteLine("Reflect(f)-direct : {0:D}", new TimeSpan(DateTime.Now.Ticks - start).Milliseconds);
31:
32: start = DateTime.Now.Ticks;
33: for (long i = 0; i < count; ++i)
34: {
35: field.SetValue(d, i);
36: }
37: Console.WriteLine("Reflect(f)-normal : {0:D}", new TimeSpan (DateTime.Now.Ticks - start).Milliseconds);
38: }
39:
40: [TestMethod()]
41: public void ReflectPerformanceTest()
42: {
43: for (long i = 1000000; i > 1; i = i / 10)
44: {
45: Console.WriteLine("#####" + i + " ###### ");
46: LoopTest(i);
47: }
48: }
Result : (單位:微秒)
#####1000000 ######
----- loop count : 1000000 -----
Class(p) : 12
Reflect(p) : 845
Class(f) : 11
Reflect(f)-direct : 230
Reflect(f)-normal : 810
#####100000 ######
----- loop count : 100000 -----
Class(p) : 1
Reflect(p) : 269
Class(f) : 1
Reflect(f)-direct : 119
Reflect(f)-normal : 163
#####10000 ######
----- loop count : 10000 -----
Class(p) : 0
Reflect(p) : 26
Class(f) : 0
Reflect(f)-direct : 12
Reflect(f)-normal : 16
#####1000 ######
----- loop count : 1000 -----
Class(p) : 0
Reflect(p) : 3
Class(f) : 0
Reflect(f)-direct : 1
Reflect(f)-normal : 2
#####100 ######
----- loop count : 100 -----
Class(p) : 0
Reflect(p) : 0
Class(f) : 0
Reflect(f)-direct : 0
Reflect(f)-normal : 0
#####10 ######
----- loop count : 10 -----
Class(p) : 0
Reflect(p) : 0
Class(f) : 0
Reflect(f)-direct : 0
Reflect(f)-normal : 0
結論:
1. 直接對物件給值最快. (廢話)
2. Field 比 Property快.
3. Field.SetValueDirect 比 SetValue 快.
同場加映 – Java 版
在Java 1.6測試下, 發現第一輪會很慢, 之後就快很多(1千萬筆下 4,778 vs 2,963).