哪个更快更好,Switch Case 还是 if else if?

83

if和switch哪个更好、更快?

if(x==1){
  echo "hi";
} else if (x==2){
  echo "bye";
}

switch(x){
  case 1
    ...
  break;
  default;
} 

36
过早优化 - 两种选择都不会节省太多时间。选择对你来说更易读的方式即可。 - DCoder
3
由于"switch"不进行比较,所以它略微快一些。 - Marduk
2
@Marduk,如何在switch语句中不进行比较? - will
2
@Marduk:你认为 x1 是如何比较的?没错,内部也执行了一个 == 比较。 - ThiefMaster
1
请不要深入代码,先生。我不是在问逻辑,我在问哪种方法更好,是if还是switch。 - Ballu Rocks
显示剩余4条评论
9个回答

169

你的第一个例子是错误的,你需要使用elseif而不是只有else

如果你使用if..elseif...或者switch主要取决于个人喜好,它们的性能是相同的。

然而,如果所有条件都是形如x == value的,其中x在每个条件中都是一样的,那么使用switch通常是有意义的。另外,我只会在有两个以上条件时才使用switch

当变量部分是函数调用时,switch实际上可以提高性能:

switch(some_func()) {
    case 1: ... break;
    case 2: ... break;
}

然后,只有在使用some_func()时才会调用一次。

if(some_func() == 1) {}
elseif(some_func() == 2) {}

如果这样写会导致函数调用两次——包括函数可能造成的副作用。不过,你可以使用 $res = some_func(); 然后在你的 if 条件中使用 $res,这样就可以完全避免这个问题。

当你有更复杂的条件时,你无法使用 switch。因为 switch 只适用于常量值的 x == y 情况。


4
你曾经说过使用 if elseif 或 switch 主要是个人偏好问题,性能相同。我不同意,switch 语句只被评估一次,然后将结果与每个 case 进行比较,而 if elseif 则会反复进行评估。因此,我认为根据条件的位置和方式,一个比另一个更快、更合适。 - jortsc
5
实际上有一种处理复杂条件的 switch case 写法:= 0: ...; break; } - SenseException
1
In PHP, you can also write 'else if' (in two words) and the behavior would be identical to the one of 'elseif' (in a single word). - A Friend
@AFriend 尽管(根据我上次查看的情况),使用单词“elseif”的性能略佳,因为解释器只需处理一条指令,而不是两条。 - Andrew Dinmore
1
@AFriend 我看到你的两个集合在速度上来回变化。不过它们之间的差异非常小;其他在服务器上运行的东西和对其他操作的处理器高速缓存可能会对测试产生同等或更大的影响。一旦它进入 opcache,可能根本没有任何区别,但是在第一次通过时,独立的单词肯定会慢一些,因为它们将被视为单独的标记。尽管如此,这种差异对于现实世界而言微不足道,甚至可以说是无关紧要的,只是为了增加兴趣而提到。 - Andrew Dinmore
显示剩余2条评论

36
根据phpbench.com,使用if/elseif语句会稍微更快一些,尤其是在使用严格比较(===)时。

enter image description here

但仅当您想要在将被调用数千次的函数中节省微秒时,它才真正重要。


4
这是一个不错的答案,但是你需要添加更多信息才能使它成为有用的答案。至少要链接到phpbench.com网站中的相关部分,并在答案中直接引用重要的内容。我将编辑您的帖子以展示格式良好的答案是什么样子。 - Hurricane Development
1
尽可能添加源代码,并且最好附上文档链接和引用。 - Jon Doe
CRAP指数又称圆形复杂度指数,证明了它的有效性。NPATH是switch语句的简写。 - Digital Human

21

一般规则是在条件数量大于3的情况下使用switch(为了可读性)。

if / else if / else更加灵活(因此更好),但switch稍微更快,因为它只计算一次条件,然后检查输出,而if每次都要这样做。

编辑:看起来switchif慢,毕竟如此,请参考http://www.phpbench.com/


3
在您的基准测试中,“switch”和“if/else”只针对两种情况进行比较。我知道在C#中,“switch”会使用查找表,并且在5个或更多选项时会更快。我进行了与您基准测试相同的性能测试,但是有10个选项而不是2个,结果表明“switch”更快! - darkheir
对于少量的比较,是的。但正如darkheir所提到的,对于其他情况并不正确。 - pcarvalho
4
通常的规则是使用......(需要引用来源)。另请参见https://dev59.com/X2w05IYBdhLWcg3wXAmF。 - Pacerier
我发现 if / else if 比 switch 语句更易于阅读,因为它们的大括号可以快速地带你进入代码块,而在 switch 语句中,找到 break 语句需要一些运气。而在 if 语句中,即使是记事本也会跟踪大括号并提供缩小代码块的选项。 - user889030

4
使用==时,if ... elseifswitch的性能几乎相同。然而,使用===时,if ... elseif的速度大约快3倍(根据:phpbench)。
一般来说,应选择最易读的方式,并在进行3个以上比较时使用switch。如果性能是主要问题,并且不需要进行任何类型转换,则使用带有===if ... elseif

2

Switch比if更快,因为switch使用跳转表,跳转表由编译器在编译时制作并由CPU /操作系统运行。例如,如果您有100个情况,并且您将在第100个情况中获得值,那么您认为它会运行所有99个条件吗?不会的,它将通过跳转表直接跳转到第100个情况。那么我们如何证明这一点呢?如果你在开头写default语句然后运行程序,你会得到默认值吗?不会,由于跳转表,你会得到你想要的答案。它知道默认值在哪里,你分配的值在哪里,它将直接带你到你想要的答案。 谈论哪个更好... if可以完成的每项工作都可以在switch中完成。 但对于较少的条件,if更好;对于更多的条件,switch更好。例如,在3个条件以下,if是好的。之后,一个好的程序员使用switch。就是这样


2

这要看具体用途。如果您的 FXP 状态(在线、离开、请勿打扰、下线)...),最好使用开关(switch)。

switch(status)
{
case 'online':
...
}

但如果你想要类似这样的东西。
if ((last_reply.ContainsKey(name)) && (last_reply[name] < little_ago))

或者
if (msg.ToString()[0] == '!')

最好使用if else语句。


1
我发现了这篇文章:https://gist.github.com/Jeff-Russ/2105d1a9e97a099ca1509de1392cd314,它表明使用 switch/case 比 if/elseif 更快,并且嵌套的 if 语句更加合理,结果也更好。
它们的时间分别是:
嵌套的 if/elseif === :0.25623297691345(嵌套的if)
switch/case:0.33157801628113(switch case)
if/elseif with === :0.45587396621704(扁平的if)
仅有 if with === :0.45587396621704(只有if)

0

我相信编译器最终会将它们转换为非常相似甚至相同的代码。

除非你在做一些奇怪的事情,否则不要试图为编译器进行优化。

此外,开发人员的时间通常比运行时间更重要(游戏除外),因此最好使其更易读和可维护。


0

在我看来,“if/else”比“switch”更快,但并不比它更好。但是我更喜欢这个:

echo ($x==1?"hi":($x==2?"bye":""));

如果你必须要做1,2种情况,比如if/else if/else


9
如果意见有数据和事实支持,那么它们是好的。 - Pacerier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接