C#enum枚举解析(含IL解析)(三)
Enum基准测试
枚举的速度是很快的,几乎不存在性能问题。枚举仅仅是像int类型一样的语法糖,也很快。
Version 1
这版代码用于测试枚举值。我们在紧密的循环中进行多次迭代。
Version 2
此版代码测试int。通过对比这两版本的代码,我们可以看到来自枚举的任何可能的性能影响。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Drawing; 6 using System.Windows.Forms; 7 using System.Diagnostics; 8 9 namespace BenchmarkEnumDemo 10 { 11 class Program 12 { 13 enum TestType 14 { 15 None, 16 Valid, 17 Invalid 18 } 19 20 const int _max = 10000000; 21 static void Main(string[] args) 22 { 23 //Version 1 : use enum in if -statement 24 var s1 = Stopwatch.StartNew(); 25 var temp1 = TestType.Valid; 26 for (int i = 0; i < _max; i++) 27 { 28 if (temp1 == TestType.Invalid) 29 { 30 return; 31 } 32 } 33 s1.Stop(); 34 35 //Version 2 : use int if if-statement 36 var s2 = Stopwatch.StartNew(); 37 var temp2 = 0; 38 for (int i = 0; i < _max; i++) 39 { 40 if (temp2 ==2) 41 { 42 return; 43 } 44 } 45 s2.Stop(); 46 47 Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds*1000000)/_max).ToString("0.00ns")); 48 Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00ns")); 49 } 50 } 51 }
IL和Enum
我们可以通过检查编译后的C#程序的IL来确定枚举的准确性能。枚举用Idc.i4加载。
这意味着“加载4字节的常量整数”。所以,一个4字节整数的枚举,准确来说像其它的常量整数一样。
这有一个enum、3个const ints和3个static readonly ints。IL显示了如何将值加载到计算堆栈上。
1 using System; 2 3 enum Test 4 { 5 Cat, 6 Dog, 7 Rabbit 8 } 9 10 class Program 11 { 12 const int _cat = 0; 13 const int _dog = 1; 14 const int _rabbit = 2; 15 16 static readonly int _cat2 = 0; 17 static readonly int _dog2 = 1; 18 static readonly int _rabbit2 = 2; 19 20 static void Main() 21 { 22 Method(Test.Cat); 23 Method(Test.Dog); 24 Method(Test.Rabbit); 25 26 Method(_cat); 27 Method(_dog); 28 Method(_rabbit); 29 30 Method(_cat2); 31 Method(_dog2); 32 Method(_rabbit2); 33 } 34 35 static void Method(Test test) 36 { 37 } 38 39 static void Method(int value) 40 { 41 } 42 } 43 .method private hidebysig static void Main() cil managed 44 { 45 .entrypoint 46 .maxstack 1 47 L_0000: ldc.i4.0 48 L_0001: call void Program::Method(valuetype Test) 49 L_0006: ldc.i4.1 50 L_0007: call void Program::Method(valuetype Test) 51 L_000c: ldc.i4.2 52 L_000d: call void Program::Method(valuetype Test) 53 L_0012: ldc.i4.0 54 L_0013: call void Program::Method(int32) 55 L_0018: ldc.i4.1 56 L_0019: call void Program::Method(int32) 57 L_001e: ldc.i4.2 58 L_001f: call void Program::Method(int32) 59 L_0024: ldsfld int32 Program::_cat2 60 L_0029: call void Program::Method(int32) 61 L_002e: ldsfld int32 Program::_dog2 62 L_0033: call void Program::Method(int32) 63 L_0038: ldsfld int32 Program::_rabbit2 64 L_003d: call void Program::Method(int32) 65 L_0042: ret 66 }
枚举和整型常量是用ld.c加载的,所以它们的性能相同。但是静态整型是用ldsfld加载的,比较慢。