使用开关:
switch($page){
case 'dog':
case 'cat':
case 'robot':
case 'default':{
break;
};
default:{
break;
}
}
使用if:
if($page == 'dog' || $page == 'cat' || $page == 'robot' || $page == 'default'){
}else{
}
使用针和&干草堆:
$pages = array('dog', 'cat', 'robot', 'default');
if(in_array($page, $pages)){
}else{
}
我想知道幕后发生了什么。
答案 0 :(得分:4)
使用VLD输出的所有方案(PHP 5.6.4)
<强>开关强>
number of ops: 31
compiled vars: !0 = $page
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > EXT_STMT
1 ASSIGN !0, 'default'
3 2 NOP
4 3 EXT_STMT
4 CASE ~1 !0, 'dog'
5 > JMPZ ~1, ->7
5 6 > > JMP ->10
7 > EXT_STMT
8 CASE ~1 !0, 'cat'
9 > JMPZ ~1, ->11
6 10 > > JMP ->14
11 > EXT_STMT
12 CASE ~1 !0, 'robot'
13 > JMPZ ~1, ->15
7 14 > > JMP ->18
15 > EXT_STMT
16 CASE ~1 !0, 'default'
17 > JMPZ ~1, ->23
18 > NOP
9 19 EXT_STMT
20 > BRK 1, ->30
11 21* EXT_STMT
22* JMP ->25
23 > EXT_STMT
24 > JMP ->29
25 > NOP
13 26 EXT_STMT
27 > BRK 1, ->30
15 28* JMP ->30
29 > > JMP ->25
16 30 > > RETURN 1
如果强>
number of ops: 16
compiled vars: !0 = $page
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > EXT_STMT
1 ASSIGN !0, 'default'
3 2 EXT_STMT
3 IS_EQUAL ~1 !0, 'dog'
4 > JMPNZ_EX ~1 ~1, ->7
5 > IS_EQUAL ~2 !0, 'cat'
6 BOOL ~1 ~2
7 > > JMPNZ_EX ~1 ~1, ->10
8 > IS_EQUAL ~3 !0, 'robot'
9 BOOL ~1 ~3
10 > > JMPNZ_EX ~1 ~1, ->13
11 > IS_EQUAL ~4 !0, 'default'
12 BOOL ~1 ~4
13 > > JMPZ ~1, ->15
5 14 > > JMP ->15
针和&amp;草堆强>
number of ops: 17
compiled vars: !0 = $page, !1 = $pages
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > EXT_STMT
1 ASSIGN !0, 'default'
3 2 EXT_STMT
3 INIT_ARRAY ~1 'dog'
4 ADD_ARRAY_ELEMENT ~1 'cat'
5 ADD_ARRAY_ELEMENT ~1 'robot'
6 ADD_ARRAY_ELEMENT ~1 'default'
7 ASSIGN !1, ~1
4 8 EXT_STMT
9 EXT_FCALL_BEGIN
10 SEND_VAR !0
11 SEND_VAR !1
12 DO_FCALL 2 $3 'in_array'
13 EXT_FCALL_END
14 > JMPZ $3, ->16
6 15 > > JMP ->16
9 16 > > RETURN 1
正如您所看到的那样,交换机实际上拥有最多的操作,但是在您的测试用例中是最快的(有兴趣看到它,因为我想这些方法中的每一种都可以是某种情况下的“最佳”)< / p>
虽然操作不是标准的工作量,但它们确实给出了指示。
稍微比较
Switch使用了很多CASE
(检查2个值相等)和JMPZ
(如果地址为零则跳转)。
如果语句使用IS_EQUAL
,这与大小写类似,但第二个值必须是常量。我认为这会减慢检查速度,因为现在有2个变量可以检查。 (您的基准测试结果似乎与此一致)
下一个使用函数调用。 PHP中的函数通常被认为很慢 https://github.com/php/php-src/blob/df29df7ec40cf7950a98f36bfa99ef19f0950309/ext/standard/array.c#L1595
是函数的C源,每种类型的变量都有不同的逻辑。假设我们使用字符串,则循环数组并使用
检查每个值尽可能早退。
基准脚本
$max_checks = 1000000;
$bench = -microtime(true);
for($i = 0;$i < $max_checks; $i++) {
switch($page){
case 'dog':
case 'cat':
case 'robot':
case 'default':{
break;
};
default:{
break;
}
}
}
echo "\nSwitch took " . (microtime(true) + $bench);
$bench = -microtime(true);
for($i = 0;$i < $max_checks; $i++) {
$page == 'dog' || $page == 'cat' || $page == 'robot' || $page == 'default';
}
echo "\nif took " . (microtime(true) + $bench);
$pages = array('dog', 'cat', 'robot', 'default');
$bench = -microtime(true);
for($i = 0;$i < $max_checks; $i++) {
(in_array($page, $pages));
}
echo "\nneedle haystack took " . (microtime(true) + $bench);
传入$page = 'dog';
Switch took 0.31698203086853
if took 0.18721604347229
needle haystack took 1.5701420307159
传递$page = 'default';
Switch took 0.46866297721863
if took 0.40072298049927
needle haystack took 1.6747360229492
传递$page = 'no match';
Switch took 0.52629804611206
if took 0.40276217460632
needle haystack took 1.6838929653168
我不确定你使用了什么输入,但是对于我而言切换是否相似(切换边缘以便更具可读性)
编辑:
另外1个更快的测试用例。
使用if ===
这会使用IS_EQUAL
IS_IDENTICAL
次来电
有一点点加速
适用于所有测试用例
if took 0.43217587471008
if(===) took 0.39284706115723
操作码列表 http://php.net/manual/en/internals2.opcodes.list.php
修改数字2
因为我无论如何都在测试PHP 7 RC3。
重新运行基准(在同一台机器上)
$page = 'dog';
Switch took 0.018393993377686
if took 0.030646085739136
if(===) took 0.036449909210205
needle haystack took 0.045974969863892
$page = 'default';
Switch took 0.040921211242676
if took 0.085216999053955
if(===) took 0.1043848991394
needle haystack took 0.052649974822998
$page = 'no match';
Switch took 0.059795141220093
if took 0.080615997314453
if(===) took 0.10486197471619
needle haystack took 0.049200057983398
使用PHP 7,针和干草堆看起来最好