使用开关:
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{
}
I would like to kNow what is happening under-the-hood.
平均速度:
>针执行时间:0.054877042770386秒
>如果执行时间:0.014014959335327秒
>开关执行时间:0.0093550682067871秒
解决方法:
开关
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
针和草垛
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
正如你所看到的那样,交换机实际上拥有最多的操作,但是在你的测试用例中是最快的(有兴趣看到它,因为我想这些方法中的每一种都可以是某种情况下的“最佳”)
虽然操作不是标准的工作量,但它们确实给出了指示.
一点比较
Switch使用了很多CASE(检查2个值相等)和JMPZ(如果地址为零则跳转).
如果语句使用IS_EQUAL,这与case类似,但第二个值必须是常量.我认为这会减慢检查速度,因为现在有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 =’不匹配’;
Switch took 0.52629804611206
if took 0.40276217460632
needle haystack took 1.6838929653168
我不确定你使用了什么输入,但是对于我来说是否和切换类似(为了更易读,切换边缘)
编辑:
另外1个测试用例更快.
使用if = ===
这将使用IS_IDENTICAL替换IS_EQUAL调用
有一点点加速
适用于所有测试用例
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 =’不匹配’;
Switch took 0.059795141220093
if took 0.080615997314453
if(===) took 0.10486197471619
needle haystack took 0.049200057983398
使用PHP 7,针和干草堆看起来最好