Switch的C#内部实现

https://www.cnblogs.com/Interkey/p/3730432.html

在IL汇编语言中的Switch指令 -- 按照标号来进行跳转(和goto语句中的标号相同)
  执行IL中Switch指令时,从运算栈顶弹出一个无符号整数,然后跳转到整数对应的标号位置继续执行
  如果整数值没有对应的标号,则忽略switch指令,调到switch指令之后的一条指令开始执行。

详细分析:

  -- 结论 (实验过程见原网页)  

1. 整数参数的Switch语句  

1a. 连续的整数
    c#的switch的case语句对应IL的switch指令中的case子句

1b. 不连续的但是相近的整数
    c#的switch的case语句对应IL的switch指令中的case子句,
    但是对于case指令之间的"缝隙"整数,会自动跳转default子句的地址

1c. 很不连续的整数
    如果按1b的思路,缝隙很大的话,IL中switch指令会凭空增加很多指向default子句指向地址的case子句
    编译器不使用switch指令,而是使用了beq指令 -- 取值若相等则跳转到目标位置,否则继续下一个取值

2. 枚举类型的Switch语句
  与对待整数没有差别,因为枚举值就是按照整数对待的;如果枚举成员的取值不连续,则对应1b或1c

3. string类型的Switch语句

3a. case子句数量<=4时
  string是引用类型参数
  同样在IL中没有使用switch指令
    如果参数为null的话,则执行流程直接跳转到case null的指令块中
    否则,比较参数与case语句对应string的相等性(==),若相等,则跳转到对应的地址后,跳出switch
  -- 这就相当于被编译成了一连串的if语句
    那么,当case子句过多时,岂不是会导致程序变慢?

3b. case子句数量>4时
  如果不是null的话,则会实例化一个字典泛型类 System.Collections.Generic.Dictionary`2<string,int32>
  将分别出现在case子句中的string作为key插入到字典中,每个key的value分别对应从0开始的整数(switch子句的序号)
  调用字典的TryGetValue()尝试从字典中找到string参数所对应的字典元素
  如果在字典中没找到,则跳转到default子句对应的位置
  如果找到了,这里出现了switch指令,根据从字典中取到的value整数值,进行switch子句的跳转
    switch之后的一条指令则为一个无条件跳转,直接跳转到default子句
    这里是当switch指令在栈顶取到的整数值比switch指令中跳转地址数量要大时,忽略switch直接执行之后的指令

总结:

3b情况下,由于Dictionary<TKey,TValue>类型通过key来取值的时间复杂度接近于O(1) -- 有助于提高效率

为了微乎其微的效率提升
  1. 尽量在switch中使用连续的取值
  2. 如果取值不连续,则使用尽量少的case子句,并将会出现频率高的case放在前面(与if...else if...else类似)
  3. 如果使用了大量if语句来判断一个字符串对象是否具有某值,改用Switch
  4. 有其他引用类型对象想要使用switch判断但又不能使用时,可以按照3b的思路自己实现。

C#_Switch语句的内部实现的更多相关文章

  1. 当程序执行一条查询语句时,MySQL内部到底发生了什么? (说一下 MySQL 执行一条查询语句的内部执行过程?

    先来个最基本的总结阐述,希望各位小伙伴认真的读一下,哈哈: 1)客户端(运行程序)先通过连接器连接到MySql服务器. 2)连接器通过数据库权限身份验证后,会先查询数据库缓存是否存在(之前执行过相同条 ...

  2. 【BigData】Java基础_switch语句

    语法 switch(表达式) { case x: // 代码块 break; case y: // 代码块 break; default: // 代码块 } switch语句是这样工作的: switc ...

  3. C#_switch语句,for循环,do while循环,while循环

    1:switch语句,代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Tex ...

  4. C++_系列自学课程_第_12_课_语句_《C++ Primer 第四版》

    前面的文章说完了表达式和类型转换的部分内容,在我参考的书里面,接下来讨论的是各种语句,包括:顺序语句.声明语句.复合语句(块语句).语句作用域 .if语句.while语句.for语句.do...whi ...

  5. 详解Python中的循环语句的用法

    一.简介 Python的条件和循环语句,决定了程序的控制流程,体现结构的多样性.须重要理解,if.while.for以及与它们相搭配的 else. elif.break.continue和pass语句 ...

  6. MyBatis学习(二)、SQL语句映射文件(2)增删改查、参数、缓存

    二.SQL语句映射文件(2)增删改查.参数.缓存 2.2 select 一个select 元素非常简单.例如: <!-- 查询学生,根据id --> <select id=" ...

  7. 关于使用READ TABLE语句的几点注意事项

    原文地址   http://www.dlsap.com/thread-34-1-1.html 1.  如果使用READ TABLE语句来读取内部表数据,而不是简单看返回值判断是否存在,那么在使用REA ...

  8. SQL 操作语句

    SQL Server T-SQL高级查询 高级查询在数据库中用得是最频繁的,也是应用最广泛的. Ø 基本常用查询 --select select * from student; --all 查询所有 ...

  9. 二、SQL语句映射文件(2)增删改查、参数、缓存

    //备注:该博客引自:http://limingnihao.iteye.com/blog/106076 2.2 select 一个select 元素非常简单.例如: Xml代码 收藏代码 <!- ...

随机推荐

  1. Ubuntu 64 + IntelliJ IDEA + Genymotion 搭建Android开发环境

    环境搭建所需可至 http://pan.baidu.com/s/1gd1Kf4Z 下载 注:     此处假定 Ubuntu 用户名为 chenfei     开发相关全部存放在 /home/chen ...

  2. 【笔记】关于TCP三次握手和四次挥手的理解

    1. 三次握手: 服务器一定处于Listen状态,否则客户端发过来的连接会被拒绝.注:服务器和客户端的角色是相对的. 客户端发送第一次握手(客户端发送连接请求(SYNC包)到服务器)之后由Closed ...

  3. swift的enum模式—对Alamofire入口的解析--数据结构与操作结合的模式

    swift的枚举模式是数据结构与操作结合的模式 1.enum本质是一个类型,可以定义变量: 它定义的变量可以用到其它变量用的的任何地方:函数的输入.输出.成员变量.临时变量等: 这个变量还可以带有附加 ...

  4. KVOController原理解析

    1.使用类似动态代理的模式和消息派发中枢模式实现整个架构: 2.使用NSMapTable和NSHashTable进行切面信息的增删查维护:主要用于去重和查看是否存在. 实现方式 消息流 KVOCont ...

  5. IOS的滑动菜单(Sliding Menu)的具体写法(附代码)

    滑动菜单是一个很流行的IOS控件 先上效果图:        这里使用github的JTReveal框架来开发,链接是https://github.com/agassiyzh/JTRevealSide ...

  6. HBase学习之路 (一)HBase基础介绍

    产生背景 自 1970 年以来,关系数据库用于数据存储和维护有关问题的解决方案.大数据的出现后, 好多公司实现处理大数据并从中受益,并开始选择像 Hadoop 的解决方案.Hadoop 使用分 布式文 ...

  7. zoc license code

    点击导航栏上的zoc-about zoc,然后: 点击enter license: 然后输入内容即可: part A:  51698/01027/34713 part B:  00937 还有很多其他 ...

  8. active developer path ("/Applications/Xcode.app/Contents/Developer")

    -> git xcrun: error: active developer path ("/Applications/Xcode.app/Contents/Developer" ...

  9. P1006 传纸条

    题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是 ...

  10. ubuntu16.04系统gcc下降和升级

    gcc下降 1 安装 sudo apt-get install -y gcc-4.7 sudo apt-get install -y g++-4.7 2 重新建立软连接 cd /usr/bin #进入 ...