【问题标题】:Does the order of cases matter in PHP switch statements?PHP switch 语句中 case 的顺序是否重要?
【发布时间】:2009-07-14 12:46:00
【问题描述】:

在 PHP switch 语句中,将更常见的情况放在顶部附近是否会提高性能?

例如,假设以下函数被调用 1000 次:

<?php 
function foo_user ($op) {
    switch ($op) {
        case 'after_update':
        //Some Stuff
        case 'login':
        //Some other Stuff
    }
}

如果在调用函数的 1000 次中有 990 次调用 $op 参数是“登录”,那么通过在 switch 语句中将 case: 'login' 设置在 case 'after_update': 之上会提高性能吗?比如$op = login通过了,case 'after_update':后面的代码会被忽略吗?

我已经对这个想法进行了一些非正式的测试,但差异可以忽略不计——也许是因为case: 'login'case 'after_update': 之后的代码都是微不足道的。如果有人完全知道答案,我宁愿避免使用非平凡操作设置更广泛的测试。

这是一个专门的 Drupal 问题,但我想任何熟悉优化 PHP 的人都可以解决。

【问题讨论】:

    标签: php optimization drupal micro-optimization


    【解决方案1】:

    这很可能被称为微优化。我不相信会有很大的不同。

    但是,如果您允许案例失败,那么顺序对于 switch 案例的逻辑确实意义重大,例如

    switch ($var) {
    
        case 0:
        case 1:
           do_it();
           break;
        case 2:
           do_it_else();
           break;
    
    }
    

    顺序很重要,案例将通过并执行任何代码,直到遇到中断。

    除非您说 100 种可能的情况,否则我不会担心 switch 案例的速度。但如果那样的话,你很可能应该重构你的代码。

    【讨论】:

      【解决方案2】:

      您将需要超过 1000 个案例才能注意到差异,但是是的,存在差异。我写了一个测试:

      function test_switch($value) {
      
        $startTime = time() + microtime();
      
        for ($i = 0; $i < 10000000; $i++) {
      
          switch($value) {
      
          case "abcdefg":
            $j = $j + 1;
            break;
          case "hijklmno":
            $j = $j + 1;
            break;
          }
        }
      
        $endTime = time() + microtime();
      
        echo "Total time for argument $value: " . ($endTime - $startTime) . "<br>\n";
      }
      
      test_switch("abcdefg");
      test_switch("hijklmno");
      

      这是 switch 语句的 1000 万次执行。输出是:

      Total time for argument abcdefg: 3.99799704552
      Total time for argument hijklmno: 5.38317489624
      

      因此存在差异,但在您达到大约 1000 万次执行之前不会明显,这当然取决于您的处理器。

      【讨论】:

        【解决方案3】:

        如果您不使用break; 关闭每个语句,PHP 将继续评估案例直到switch 块结束,这可能会影响足够大块中的性能。然后,顺序对于获得您正在寻找的行为变得很重要。

        来自PHP.Net

        switch 语句逐行执行(实际上是逐语句执行)。一开始,没有代码被执行。只有当 case 语句的值与 switch 表达式的值匹配时,PHP 才会开始执行语句。 PHP 会继续执行这些语句,直到 switch 块结束,或者它第一次看到 break 语句。如果你不在一个case语句列表的末尾写一个break语句,PHP会继续执行下一个case的语句。例如:

        <?php
            switch ($i) {
                case 0:
                    echo "i equals 0";
                case 1:
                    echo "i equals 1";
                case 2:
                    echo "i equals 2";
            }
        ?>
        

        我会告诫不要依赖这种行为,并为每个 case 使用 break;,因为这样可以在您稍后重新访问代码时消除一些歧义。

        【讨论】:

          【解决方案4】:

          通常建议先写最可能的case,再写第二个...

          但就像亚历克斯写的那样,

          这很可能被称为 微观优化。我不相信 会有很大的不同。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-04-15
            • 1970-01-01
            • 2012-07-26
            • 2013-09-24
            • 1970-01-01
            相关资源
            最近更新 更多