在 PHP、大型 switch 语句或每次都支付数组初始化费用的数组键查找中,什么更快?

2022-08-30 16:44:16

在 PHP 中,制作大型 switch 语句或设置数组并查找密钥的速度更快吗?

现在,在你回答之前,我很清楚,对于纯查找,数组更快。但是,这是假设只创建数组一次,然后反复查找它。

但这不是我正在做的 - 每次运行代码都是新的,数组每次只使用一次。因此,每次都需要重新计算所有数组哈希值,我想知道进行该设置是否比简单地拥有语句慢。switch


答案 1

我做了一些测试:

文件array_gen.php

<?
    echo '<?
        $a = 432;
        $hash = array(
    ';

    for($i = 0; $i < 10000; $i++)
        echo "$i => $i,\n";

    echo ');
        echo $hash[$a];
    ';

文件switch_gen.php:

<?
    echo '<?
        $a = 432;
        switch($a) {
    ';
    for($i = 0; $i < 10000; $i++)
        echo "case $i: echo $i; break;\n";

    echo '}';

然后:

php array_gen.php > array_.php
php switch_gen.php > switch.php

time tcsh -c 'repeat 1000 php array.php > /dev/null'
19.297u 4.791s 0:25.16 95.7%
time tcsh -c 'repeat 1000 php switch.php > /dev/null'
25.081u 5.543s 0:31.66 96.7%

然后我修改了循环:

for($i = 'a'; $i < 'z'; $i++)
  for($j = 'a'; $j < 'z'; $j++)
    for($k = 'a'; $k < 'z'; $k++)

要创建 17576,3 个字母组合。

time tcsh -c 'repeat 1000 php array.php > /dev/null'
30.916u 5.831s 0:37.85 97.0%
time tcsh -c 'repeat 1000 php switch.php > /dev/null'
36.257u 6.624s 0:43.96 97.5%

数组方法每次都获胜,即使包含设置时间也是如此。但不是很多。所以我想我会忽略这种优化,去做任何更容易的事情。


答案 2

它在某种程度上取决于数组大小,但对于大多数实际目的,您可以考虑数组更快。原因很简单;switch 语句必须与 switch 语句中的每个条目按顺序进行比较,但数组方法仅采用哈希并找到该条目。如果交换机中的条目太少,以至于顺序比较比哈希更快,则使用交换机更快,但数组方法会更快地变得更有效。在计算机科学术语中,这是一个O(n)与O(1)的问题。