`

if vs. switch,测试与分析 (转)

 
阅读更多

最近在学php,看php手册的时候,突然间对if和switch的性能差别有兴趣,在网上查了不少资料,最后看到这篇文章,终于让我发现平时在写代码的进候的一个错误,喜欢用if ..else多于switch,实际上switch的性能要比if ..else高多了.特引用此文于此,以后写代码时候多多注意.

记得在很久以前,博客园上一个哥们抱怨.net的源码写的太烂,到处都是switch,我当时就做过一个测试,证实了switch比if性能高许多。今天又看见这个话题,呵呵,那就再做个测试吧。

代码:


<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->usingSystem;
usingSystem.Collections.Generic;
usingSystem.Diagnostics;
usingSystem.Text;

namespaceConsoleApplication1
{
classProgram
{
staticInt32Count=100000000;

staticInt32TestIfElse(Int32value)
{
Int32i
=0;


Stopwatchsw
=newStopwatch();
sw.Start();
for(intj=0;j<Count;j++)
{
if(value==1)
i
+=1;
elseif(value==2)
i
+=2;
elseif(value==3)
i
+=3;
elseif(value==4)
i
+=4;
elseif(value==5)
i
+=5;
}

sw.Stop();
Console.WriteLine(
"TestIfElse:"+sw.ElapsedMilliseconds);
returni;
}


staticInt32TestSwitch(Int32value)
{
Int32i
=0;

Stopwatchsw
=newStopwatch();
sw.Start();

for(intj=0;j<Count;j++)
{
switch(value)
{
case1:
i
+=1;
break;
case2:
i
+=2;
break;
case3:
i
+=3;
break;
case4:
i
+=4;
break;
case5:
i
+=5;
break;
default:
break;
}

}

sw.Stop();
Console.WriteLine(
"TestSwitch:"+sw.ElapsedMilliseconds);

returni;
}


staticvoidMain(string[]args)
{
TestIfElse(
5);
TestSwitch(
5);
Console.Read();
}

}

}

release下编译,测试结果:

TestIfElse: 613
TestSwitch: 165

4倍左右的性能差距。反编译看il,会发现TestSwitch方法中多了这么一句:

switch (L_0032, L_0038, L_003e, L_0044, L_004a)

这句话实现了一个 jump table。

正如一线工作者所言,这个switch 指令是一个有索引的跳转,而if ... else 是无索引的跳转。if...else 是 O(N)级别的,switch ... case 是 O(1)级别的。

如果将上面测试代码的分支增加到10支,测试TestSwitch(10)与TestIfElse(10)的性能,会发现前者比后者几乎快7-8倍。

详细解释请参见《深入理解计算机系统》一书中的某章(忘了哪个章节,书不在身边,里面讲了switch和if的区别)。也可参考这篇文章:http://www.9php.com/FAQ/cxsjl/c/2008/10/1435098132356.html。.net下的分析见:http://www.cnblogs.com/yeah/archive/2009/02/16/1392094.html

如果switch(String ..),测试了一下,switch与if...else性能相当。我原以为为是无法生成跳转表,刚看完http://www.cnblogs.com/yeah/archive/2009/02/16/1392094.html这篇文章,发现还是可以生成跳转表,只是这个跳转表的代价比简单的整数类型的跳转表代价高。也就是说,这种情况下,switch case 还是O(1)级别分支语句的。

分享到:
评论

相关推荐

    c#3.0语言规范高清PDF

    1. 简介 ................................................................................................................................................................... 1 1.1 Hello world .............

    C#教程(语言规范)

    2.3 词法分析 .. 32 2.3.1 行结束符... 33 2.3.2 注释... 33 2.3.3 空白... 34 2.4 标记 ... 34 iv C#语言规范 2.4.1 Unicode 字符转义序列 ... 35 2.4.2 标识符. 35 2.4.3 关键字. 37 2.4.4 文本... 37 ...

    测试笔记(从零开始)

    ★如何做测试需求分析 86 ★UML统一建模语言(Unified Modeling Language) 86 第十一章 配置管理 88 1.什么是配置管理 88 2.配置管理流程 88 3.SVN实战 88 配置管理工具SVN操作过程手册 90 一、 如何创建“project...

    宋劲彬的嵌入式C语言一站式编程

    4. switch语句 5. 深入理解函数 1. return语句 2. 增量式开发 3. 递归 6. 循环语句 1. while语句 2. do/while语句 3. for语句 4. break和continue语句 5. 嵌套循环 6. goto语句和标号 7. 结构体 1. 复合类型与结构体...

    Java语言程序设计与数据结构11版.ch3.docx

    Java语言程序设计与数据结构第11版第3章 本章主要介绍了Java语言的基本语法和数据结构。以下是本章的知识点总结: 1. 关系运算符:Java语言中有六种关系运算符,分别是&gt;、&lt;、&gt;=、、==、!=,用于比较两个值是否相等...

    词法分析实验报告.docx

    (1)数据结构和与语法分析程序的接口请自行定义;类别码需按下表格式统一定义; (2)为了方便进行自动评测,输入的被编译源文件统一命名为testfile.txt(注意不要写错文件名);输出的结果文件统一命名为output...

    编译原理 词法分析 源代码

    4、自己准备测试数据存放于TestData.txt文件中,测试数据中应覆盖有以上5种数据,测试结果要求以原数据与结果对照的形式输出并保存在Result.txt中,同时要把结果输出到屏幕。 5、提前准备 ① 实验前,先编制好程序,...

    编译原理实验报告 词法分析器实验报告

    程序中先判断这个句语句中每个单元为关键字、常数、运算符、界符,对与不同的单词符号给出不同编码形式的编码,用以区分之。 PL/0语言的EBNF表示 &lt;常量定义&gt;::=&lt;标识符&gt;=&lt;无符号整数&gt;; &lt;标识符&gt;::=&lt;字母&gt;={&lt;字母...

    词法分析器(Java Swing)

    void、main、include、break、bengin、end、return、if、else、do、while、switch、case 1 +、-、++、--、*、/、=、==、>、、>=、 2 (、)、{、}、[、]、; 3 标识符 4 常数 5 其他 6 (2) 语法分析的文法如下:...

    设计一个测试程序比较几种内部排序算法的关键字比较次数和移动次数以取得直观感受。

    设计一个测试程序比较几种内部排序算法的关键字比较次数和移动次数以取得直观感受。 在本文中,我们将设计一个测试程序比较几种内部排序算法的关键字比较次数和移动次数,以取得直观感受。内部排序算法是指在内存中...

    C#语言规范(2.0,3.0,4.0合集)

    2.3 词法分析 34 2.3.1 行结束符 35 2.3.2 注释 35 2.3.3 空白 36 2.4 标记 37 2.4.1 Unicode 字符转义序列 37 2.4.2 标识符 38 2.4.3 关键字 39 2.4.4 文本 41 2.4.4.1 布尔值 41 2.4.4.2 整数 41 2.4.4.3 实数 42 ...

    ZendFramework中文文档

    7.9.4. 在响应对象中测试异常 7.9.5. 子类化响应对象 7.10. 插件 7.10.1. 简介 7.10.2. 编写插件 7.10.3. 使用插件 7.10.4. 获取和控制插件 7.10.5. 包含在标准发行包中的插件 7.10.5.1. 动作堆栈 7.10.5.2...

    精通javascript

    方法与confirm()方法的使用 • 14.3.htm prompt()方法的使用 • 14.4.htm window.open()方法 • 14.5.htm 用链接和按钮实现窗口打开 • 14.6.htm 窗口的打开和关闭 • 14.7....

    精通JavaScript

    • 4.7.htm switch语句 • 4.8.htm while循环语句 • 4.9.htm do-while循环语句 • 4.10.htm for循环语句 • 4.11.htm for循环语句之二 • 4.12.htm continue语句 ...

    北大青鸟Java第二次测试笔试题

    北大青鸟Java第二次测试笔试题 本资源是一个Java笔试题库,涵盖了Java程序设计的多个方面,包括代码阅读、if-else语句、switch语句、while循环和do-while循环等。下面是对每个问题的详细解释和答案。 一、代码阅读...

    C#语言规范(4.0版本)

    2.3 词法分析 34 2.3.1 行结束符 35 2.3.2 注释 35 2.3.3 空白 36 2.4 标记 37 2.4.1 Unicode 字符转义序列 37 2.4.2 标识符 38 2.4.3 关键字 39 2.4.4 文本 41 2.4.4.1 布尔值 41 2.4.4.2 整数 41 2.4.4.3 实数 42 ...

    交换机配置

    (1) 新加入的SwitchC 默认状态时,测试连通性。 从PCA-&gt;PCC,从PCB-&gt;PCD 测试: [root@PCA root]# ping 10.65.1.3 (不通) [root@PCB root]# ping 10.66.1.3 (不通) 由于新加入的交换机没有设置trunk,所有接口默认...

    微软C#语言规范,C#语言教程中文版

    2.3 词法分析 34 2.3.1 行结束符 35 2.3.2 注释 35 2.3.3 空白 36 2.4 标记 37 2.4.1 Unicode 字符转义序列 37 2.4.2 标识符 38 2.4.3 关键字 39 2.4.4 文本 41 2.4.4.1 布尔值 41 2.4.4.2 整数 41 2.4.4.3 实数 42 ...

    C#语言规范4.0

    2.3 词法分析 34 2.3.1 行结束符 35 2.3.2 注释 35 2.3.3 空白 36 2.4 标记 37 2.4.1 Unicode 字符转义序列 37 2.4.2 标识符 38 2.4.3 关键字 39 2.4.4 文本 41 2.4.4.1 布尔值 41 2.4.4.2 整数 41 2.4.4.3 实数 42 ...

Global site tag (gtag.js) - Google Analytics