C#对switch语句的优化

原创 2006年06月22日 12:38:00
1    	一直以为C#中的switch语句在处理字符串时是用if语句来构造的,因为.net的IL中的switch也逃不脱C的宿命--只能
2    处理数字,而实际上C#编译器对switch语句对字符串的处理却让人汗啊.
3    	首先编译一下下面的代码:
4    using System;
5    class EntryPoint
6    {
7    	private static void Main()
8    	{
9    		Console.WriteLine("请输入序号:a,b,c,d,e,f");
10    		string szInput = Console.ReadLine();
11    		switch (szInput)
12    		{
13    			case "a":
14    				Console.WriteLine("你输入的是:a");	
15    				break;
16    
17    			case "b":
18    				Console.WriteLine("你输入的是:b");	
19    				break;
20    
21    			case "c":
22    				Console.WriteLine("你输入的是:c");	
23    				break;			
24    
25    			case "d":
26    				Console.WriteLine("你输入的是:a");	
27    				break;
28    
29    			case "e":
30    				Console.WriteLine("你输入的是:e");	
31    				break;
32    
33    			case "f":
34    				Console.WriteLine("你输入的是:f");	
35    				break;
36    
37    			default :
38    				Console.WriteLine("你输入的是:{0}",szInput);
39    				break;
40    		}
41    		Console.Read();
42    	}
43    }
44    
45    再用Reflector反编译上面源代码编译出来的程序,下面是反编译出来的代码
46    private static void Main()
47    {
48          Console.WriteLine("/u8bf7/u8f93/u5165/u5e8f/u53f7:a,b,c,d,e,f");
49          string text1 = Console.ReadLine();
50          string text2 = text1;
51          if (text2 != null)
52          {
53                int num2;
54                if (<PrivateImplementationDetails>{FEB70444-128D-453C-8E6F-C839E1DC2F51}.$method0x6000001-1 == null)
55                {
56                      Dictionary<string, int> dictionary1 = new Dictionary<string, int>(6);
57                      dictionary1.Add("a", 0);
58                      dictionary1.Add("b", 1);
59                      dictionary1.Add("c", 2);
60                      dictionary1.Add("d", 3);
61                      dictionary1.Add("e", 4);
62                      dictionary1.Add("f", 5);
63                      <PrivateImplementationDetails>{FEB70444-128D-453C-8E6F-C839E1DC2F51}.$method0x6000001-1 = dictionary1;
64                }
65                if (<PrivateImplementationDetails>{FEB70444-128D-453C-8E6F-C839E1DC2F51}.$method0x6000001-1.TryGetValue(text2, out num2))
66                {
67                      switch (num2)
68                      {
69                            case 0:
70                                  Console.WriteLine("/u4f60/u8f93/u5165/u7684/u662f:a");
71                                  goto Label_0105;
72    
73                            case 1:
74                                  Console.WriteLine("/u4f60/u8f93/u5165/u7684/u662f:b");
75                                  goto Label_0105;
76    
77                            case 2:
78                                  Console.WriteLine("/u4f60/u8f93/u5165/u7684/u662f:c");
79                                  goto Label_0105;
80    
81                            case 3:
82                                  Console.WriteLine("/u4f60/u8f93/u5165/u7684/u662f:a");
83                                  goto Label_0105;
84    
85                            case 4:
86                                  Console.WriteLine("/u4f60/u8f93/u5165/u7684/u662f:e");
87                                  goto Label_0105;
88    
89                            case 5:
90                                  Console.WriteLine("/u4f60/u8f93/u5165/u7684/u662f:f");
91                                  goto Label_0105;
92                      }
93                }
94          }
95          Console.WriteLine("/u4f60/u8f93/u5165/u7684/u662f:{0}", text1);
96    Label_0105:
97          Console.Read();
98    }
99    
100      可以看到C#编译器把所有case标签里的字符串按顺序存储到泛型的字典$method0x6000001-1中(键是标签值,值是标签序号
101    ).而$method0x6000001-1则是<PrivateImplementationDetails>{FEB70444-128D-453C-8E6F-C839E1DC2F51}类中的一个静态
102    字段.下面是<PrivateImplementationDetails>{FEB70444-128D-453C-8E6F-C839E1DC2F51}的代码
103    [CompilerGenerated]
104    internal class <PrivateImplementationDetails>{FEB70444-128D-453C-8E6F-C839E1DC2F51}
105    {
106          // Fields
107          internal static Dictionary<string, int> $method0x6000001-1;
108    }
109    
110      用过VC的人可能知道在VC中当swith语句中的标签大于一定的数量时VC编译器会建立一个散列表来提升case标签的查找性能
111    .呵呵!没想到这个思想在如今的C#编译器中也得到了应用,真让人喜出望外啊!
112      或许有人会认为以上的代码多了一个字典字段的初始化而switch中的标签也并没有削减可能反而会影响了性能.这些不必担
113    忧因为:
114    1,由于Dictionary的存储结构是散列结构,所以它查找起起数据来;
115    2,switch语句在IL中是直接支持的,所以不用过滤;
116    3,Dictionary字段是一个静态字段,只须初始化一次;
117    4,俺们挖空心思的优化自己的代码,还不如编译器的优化好(失败的打击).
118    
119      但是,正如VC编译器一样C#编译器并不会对所有的字符串的swith语句都用字典来存储,而是当case标签的数量在>=6个时才
120    用字典来提升查找性能.
121    
122    注意:以上的代码如果用C#1.0编译将会有所差异其中用来存储标签中的字符串的对象不是Dictionary而是HashTable.
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

c#——switch case语句

c#——switch case语句 c#中的switch case语句有三种结构,具体形式如下图所示: (1)Switch的第一种结构:(如例1) ...

unity3D-游戏/AR/VR在线就业班 C#入门Switch语句学习笔记

unity3D-游戏/AR/VR在线就业班 C#入门Switch语句学习笔记

C#的switch语句

if语句每次判断只能实现两条分支,如果要实现多种选择的功能,那么可以采用switch语句。 switch语句根据一个控制表达式的值选择一个内嵌语句分支来执行。它的一般格式为: switch(con...

C#学习 第二章 语句控制,if,switch,try-catch,whlie,foreach,break,continue,goto

以下文章为C#第二章,包括 选择结构if else,switch case,循环结构 do while,while,for,foreach,跳转语言 break,continue,goto 参考图书...

c#——switch case语句

c#中的switch case语句有三种结构,具体形式如下图所示: (1)Switch的第一种结构:(如例1) switch...

C#的switch语句(2)

使用switch语句时需注意以下几点: 不准遍历 C和C++语言允许switch语句中case标签后不出现break语句,但C#不允许这样,它要求每个标签项后使用break语句或跳转语句goto,...

C#的switch语句

出处:http://www.cnblogs.com/lmfeng/archive/2011/08/04/2127294.html.NET 中C#的switch语句的语法如下(switch,case和d...

实战c++中的string系列--将string用于switch语句(c++做C#的事儿, switch中break还是return厉害)

作为一个C++程序员,或是出于习惯,或是出于无奈,你多少次这么写:if (!strcmp(pszValue, "Value X")) DoThis(); else if (!strcmp(ps...

SWITCH语句的使用

  • 2008-11-04 18:34
  • 636B
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)