if vs. switch,测试与分析 (转)
2009-09-04 16:04
232 查看
最近在学php,看php手册的时候,突然间对if和switch的性能差别有兴趣,在网上查了不少资料,最后看到这篇文章,终于让我发现平时在写代码的进候的一个错误,喜欢用if ..else多于switch,实际上switch的性能要比if ..else高多了.特引用此文于此,以后写代码时候多多注意.
记得在很久以前,博客园上一个哥们抱怨.net的源码写的太烂,到处都是switch,我当时就做过一个测试,证实了switch比if性能高许多。今天又看见这个话题,呵呵,那就再做个测试吧。
代码:
Code
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static Int32 Count = 100000000;
static Int32 TestIfElse(Int32 value)
{
Int32 i = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
for (int j = 0; j < Count; j++ )
{
if (value == 1)
i += 1;
else if (value == 2)
i += 2;
else if (value == 3)
i += 3;
else if (value == 4)
i += 4;
else if (value == 5)
i += 5;
}
sw.Stop();
Console.WriteLine("TestIfElse: " + sw.ElapsedMilliseconds);
return i;
}
static Int32 TestSwitch(Int32 value)
{
Int32 i = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
for (int j = 0; j < Count; j++)
{
switch (value)
{
case 1:
i+=1;
break;
case 2:
i+=2;
break;
case 3:
i+=3;
break;
case 4:
i+=4;
break;
case 5:
i+=5;
break;
default:
break;
}
}
sw.Stop();
Console.WriteLine("TestSwitch: " + sw.ElapsedMilliseconds);
return i;
}
static void Main(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)级别分支语句的。
记得在很久以前,博客园上一个哥们抱怨.net的源码写的太烂,到处都是switch,我当时就做过一个测试,证实了switch比if性能高许多。今天又看见这个话题,呵呵,那就再做个测试吧。
代码:
Code
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static Int32 Count = 100000000;
static Int32 TestIfElse(Int32 value)
{
Int32 i = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
for (int j = 0; j < Count; j++ )
{
if (value == 1)
i += 1;
else if (value == 2)
i += 2;
else if (value == 3)
i += 3;
else if (value == 4)
i += 4;
else if (value == 5)
i += 5;
}
sw.Stop();
Console.WriteLine("TestIfElse: " + sw.ElapsedMilliseconds);
return i;
}
static Int32 TestSwitch(Int32 value)
{
Int32 i = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
for (int j = 0; j < Count; j++)
{
switch (value)
{
case 1:
i+=1;
break;
case 2:
i+=2;
break;
case 3:
i+=3;
break;
case 4:
i+=4;
break;
case 5:
i+=5;
break;
default:
break;
}
}
sw.Stop();
Console.WriteLine("TestSwitch: " + sw.ElapsedMilliseconds);
return i;
}
static void Main(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)级别分支语句的。
相关文章推荐
- if vs. switch,测试与分析
- VS_C_17/11/22 C中if与switch的区别
- switch 与 if else 效率分析与总结
- switch与if 性能测试
- if, switch, do , while, for分析
- C语言 if,switch,do,while,for分析
- 【编译器】if/switch之性能分析
- C++反汇编->多分支if与switch分析
- theano tutorial(六)IfElse vs Switch
- 黑马程序员————if、switch、while、for的使用分析
- C++反汇编->多分支if与switch分析
- switch 与 if else 效率分析与总结
- if switch do while for分析
- 分支语句 循环语句 if,switch,do,while,for分析
- getchar()函数的返回值赋给char型,用if(ch=getchar() != EOF)测试,输入ctrl+z同样可以结束循环的分析
- if和switch的两个测试小程序,时间上的效率和空间上的占用!
- If VS Switch
- Theano(6):Theano条件语句,IfElse vs Switch
- php中switch与ifelse的效率区别及适用情况分析
- php中switch与ifelse的效率区别及适用情况分析