`

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)级别分支语句的。

分享到:
评论

相关推荐

    Test_if_ne.rar_If...

    此外,`if...else`结构可能与其他控制结构结合使用,如`switch`语句、循环(`for`,`while`)以及递归,以实现更复杂的逻辑测试。文件名中的"ne"可能代表“not equal”,暗示测试集中可能特别关注条件不满足的情况,...

    C语言分支结构及测试代码

    C语言是一种强大的编程语言,它的分支结构是程序逻辑控制的重要组成...通过运行和分析这些代码,你可以更深入地理解C语言的条件控制,并学习如何编写和测试分支结构。同时,这也是提高编程技能和调试能力的有效方法。

    优化if/else测试代码包cheng.rar

    通过将这些状态定义为枚举成员,我们可以避免冗长的if/else链,转而使用switch语句或者直接调用枚举对象的方法。这样,代码不仅更简洁,而且枚举的静态性质保证了类型安全,减少了错误的可能性。 例如,假设有一个`...

    软件工程与软件测试技术.pdf

    综上所述,软件工程与软件测试技术涉及的内容十分广泛,包括但不限于测试工具的使用、测试方法的设计、编程知识的运用、性能测试的执行、以及代码覆盖率的分析等。掌握这些知识点对于开发和维护高质量的软件产品至关...

    JAVA_面试题集(99).doc

    12. if...else if...else if...else与switch的使用场景: if...else语句适用于任何条件判断,而switch适用于基于特定变量值的多分支选择,尤其适合于枚举类型和字符串。 13. 生成10-100之间随机数的公式: 可以...

    西南交通大学程序设计基础实验四.pdf

    一、多路分支结构与switch语句 在编程中,多路分支结构允许程序根据不同的条件执行不同的操作。实验的第一个任务是实现一个简单的剪刀石头布游戏。这里使用了if...else结构来判断两个玩家的输入并输出结果。同时,...

    (完整word版)第3套软件测试整理修订试卷.doc

    一个 if 可以有多个 else 与之匹配,且 switch 语句可以被 if...else 语句序列替换。B)错误,一个 if 只能有一个 else 与其匹配。D)break 语句仅能跳出当前循环或switch语句块。 16. QTP(QuickTest Professional...

    测试覆盖率报告

    2. 分支覆盖:确保程序中的每个逻辑分支(如if、else、switch语句)都至少被执行一次。 3. 条件覆盖:检查每个布尔表达式中的每个条件至少取到真和假两种情况。 4. 判定覆盖(也称为决策覆盖):要求每个逻辑判断的...

    (完整word版)第3套-软件测试整理修订试卷.doc

    15. **条件语句**:在 C 语言中,else 总与最近未配对的 if 匹配,一个 if 可以有多个 else 与其匹配,switch 语句可以被 if...else 语句替换,但 break 语句仅用于跳出当前循环或switch 结构。 16. **QTP 脚本显示...

    软件测试自动化.ppt

    - **代码路径覆盖挑战**:每个`if…else…`或`switch`语句都会成倍增加测试复杂度,异常处理代码难以触及。 - **产品版本与服务包**:每个产品版本及其服务包(如NT4、VS6 SP1~SP5)都需独立测试,自动化测试有助...

    C语言switch语句的一种文法改写方法.pdf

    最后,我们对该方法进行了实验和测试,结果表明该方法能够高效地实现switch语句的翻译。 本文的贡献主要在于:(1)提出了switch语句的一种文法改写方法,能够高效地实现switch语句的翻译;(2)该方法能够使得分析...

    elseif.js:嵌套ifelse语句

    标题中的"elseif.js"暗示我们将讨论与JavaScript中的`else if`(通常写作`else if`,但有时为了节省空间或个人偏好,也可能写作`elseif`)语句相关的主题。 `else if`语句是`if`语句的扩展,当最初的`if`条件不满足...

    简单计算器C语言专业课程设计方案报告书.doc

    该系统的具体设计基于系统需求分析和系统总体设计结论,采用Visual C++实现各模块功效。该系统包含三个模块: 1. 显示界面模块 2. 数学计算模块 3. 退出程序模块 程序测试 该系统的程序测试将包括以下几个方面: ...

    词法分析器-测试文档1

    例如,C语言的关键字包括 `int`, `char`, `for`, `switch`, `string`, `case`, `return`, `enum`, `union`, `cout`, `double`, `if`, `else`, `while`, `main`, `void`, `default` 等。如果需要添加或删除关键字,...

    javascript的switch用法注意事项分析

    `switch`在某些情况下比多个`if...else if...else`语句更快,因为一旦找到匹配的`case`,它就可以立即停止检查,而`if...else if`链则需要检查所有条件。 通过理解和注意这些要点,您可以更有效地利用JavaScript的...

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

    编译原理词法分析与语法分析实验报告 一、词法分析 词法分析是编译过程的第一阶段,它的主要任务是将源程序分割成单词序列。单词是编译器的基本单元,它可以是关键字、标识符、常数、运算符、分隔符等。词法分析器...

    C++实现词法分析.rar

    在“C++实现词法分析.rar”这个压缩包中,很可能是包含了一个C++编写的词法分析程序,可能包括源代码、测试用例和相关的文档。使用者可以通过查看源代码学习词法分析器的具体实现,以及如何在C++中处理编译原理的...

    时间转换.zip

    3. **条件判断和逻辑控制**:根据时间格式的要求,可能需要编写复杂的if-else语句或switch-case结构来处理不同的转换情况。 4. **效率优化**:在处理大量输入时,优化算法以减少时间复杂度,提高运行速度。 通过对...

    c语言对自己电脑系统测试.zip

    在本压缩包“c语言对自己电脑系统测试.zip”中,我们发现了一系列与C语言编程相关的资源,适合学习、实践和课程设计。C语言是一种强大的、底层的编程语言,被广泛应用于系统开发、软件工程、嵌入式系统以及各种计算...

    软件测试基本资料白盒测试指南

    4. **分支覆盖**:确保程序中的每个分支(如if语句或switch语句)至少被执行一次。这是为了检查程序在不同分支下的行为是否正确。 5. **循环覆盖**:针对循环结构进行测试,确保循环的初始化、边界条件、循环体内的...

Global site tag (gtag.js) - Google Analytics