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加载的,比较慢。

posted @ 2022-08-20 11:36  chenlight  阅读(59)  评论(0)    收藏  举报