[Reflection] Fields, Properties SetValue performance benchmark test

[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).