【问题标题】:Does having a lot of if statements degrade rendering speed of php?有很多 if 语句会降低 php 的渲染速度吗?
【发布时间】:2011-12-15 07:23:54
【问题描述】:

我想知道我的 PHP 代码中复杂的 if/else 结构是否是一个糟糕的设计决策。是否有大量 if 语句会使 PHP 运行缓慢、网站加载速度变慢等?

这是代码: (我不知道 wordpress 如何处理 is_page 等)

<?php

if (is_page()) {
//
    if (is_page(122)) {
    //subscribe page
    echo "subscribe page";

    }

    elseif (is_page(1263)) {
    //photography course
    echo "photography course page";

    }

    elseif (is_page(array(210,184,128))) {
    //210 copyright policy, 184 privacy policy, 128 contact
    echo "this is either copyright policy, privacy or contact page!";
    //nothing happens here, we don't need social buttons on these pages.
    }

    elseif (is_page(array(379,71,7,45,124,8,105,175,9,125,110))) {
    //379 photo galleries, 71 car photos, 7 conceptual, 45 event photos, 124 fashion, 8 landscape, 105 misc, 175 journalism, 9 portrait, 125 street photography, 110 travel
    echo "gallery pages and albums";

    }

    else {
    //any other page
    echo "any other page";

    }
//
}

elseif (is_single()) {
//
    if (in_category(array(147,196,35))) {
    //147 car photography, 196 car wallpapers, 35 photo stories
    echo "photo posts";

    }
    else {
    //any other post
    echo "any other post";

    }
//
}

elseif (is_archive()) {
//
    //any category
    echo "this is archive template"

}
//
?>

【问题讨论】:

  • 什么是“分配”? 10? 100? 10千亿?你在做一长串独立的ifs吗?还是 if/then/else/else/else 链?
  • 您好,感谢您的回复,我在主帖中添加了代码(因为格式正确)。请检查并告诉我您的想法! :) 谢谢。

标签: php performance


【解决方案1】:

在某种程度上..是的
我这么说是考虑到最坏的情况,在这种情况下是一个非常大的模型对象,有很多条件。在这里,代码必须经过所有条件检查,这最终会减慢代码的速度。
条件语句给并行化和向量化带来了困难,一长串的 IF-THEN 也会造成指令缓存未命中等影响。但如果这就是使代码最清晰的原因,那就使用它。

【讨论】:

    【解决方案2】:

    我刚刚从 WPShout 发现了一个非常有趣的 article 片段,它使用了一个非常人性化的类比来邀请我们更聪明地编写代码,以及为什么深度嵌套的 if { .. } 语句不仅会降低性能,还会降低代码的可维护性.如果逻辑是性能感知的,没有不必要的臃肿迭代检查,那么您很可能最终会得到一个组织良好、响应清晰的代码。

    代码示例(摘自文章)

    “让我们通过看两个简单的代码示例来具体说明这一点: 首先是气泡式,然后是网关式”。

    不好:气泡式

    $is_first_thing_working = true;
    $is_second_thing_working = true;
    $is_third_thing_working = true;
    $is_fourth_thing_working = true;
    
    if( $is_first_thing_working === true ) {
        if( $is_second_thing_working === true ) {
            if( $is_third_thing_working === true ) {
                if( $is_fourth_thing_working === true ) {
                    return 'Working properly!';
                }
                else {
                    return 'Fourth thing broken.';
                }
            }
            else {
                return 'Third thing broken.';
            }
        }
        else {
            return 'Second thing broken.';
        }
    }
    else {
        return 'First thing broken.';
    }
    

    好:网关风格

    $is_first_thing_working = true;
    $is_second_thing_working = true;
    $is_third_thing_working = true;
    $is_fourth_thing_working = true;
    
    if( $is_first_thing_working !== true ) {
        return 'First thing broken.';
    }
    
    if( $is_second_thing_working !== true ) {
        return 'Second thing broken.';
    }
    
    if( $is_third_thing_working !== true ) {
        return 'Third thing broken.';
    }
    
    if( $is_fourth_thing_working !== true ) {
        return 'Fourth thing broken.';
    }
    
    return 'Working properly!';
    

    示例说明

    上面两个代码sn-ps的区别归结为一个关键的区别:

    bubble 方法询问重要条件是否为真,只有在它们为真时才运行代码。

    网关方法询问重要条件是否为假,如果为假,则立即针对每个条件发出退出指令。

    bubble 方法强制嵌套,因为您必须先检查“true, true, true, true”,然后才能找到要运行的代码。每个 “true” 检查都是一个嵌套级别 - 您的代码必须存在于其中的条件。

    网关方法没有嵌套: 如您所见,代码的深度永远不会超过一层逻辑。这是因为一旦通过给定的网关,我们就可以完全忘记它。换句话说,由于我们在$is_first_thing_working 检查后没有退出,我们自动知道$is_first_thing_working 对于其余代码是true

    “就像现实生活一样:如果你在历史课上坐在我旁边,我 知道你是人类,我高中的学生等等——否则你 一开始就不会上我的课。无需检查。”

    【讨论】:

      【解决方案3】:

      不。事实上,在大多数情况下它实际上会加快速度(因为它允许跳过代码块)。

      如果您正在检查的条件需要处理,则只有大量 if 语句会减慢速度。一个例子是这样的:

      while (true)
      {
          if (count($some_array) == 0) { break; }
          /* some other code */
      }
      

      循环中的每一次迭代都会检查count($some_array) == 0。这意味着每次通过,PHP 都必须手动 count $some_array 中的项目数,因为它可能已经改变。这也适用于 for 循环中的停止条件。这是因为 for 循环总是可以重写为 while 循环:

      for ([INITIALIZER_ACTION]; [CONDITION]; [POST_ITERATION_ACTION]) { [CODE]; }
      

      与...相同

      [INITIALIZER_ACTION];
      while ([CONDITION]) { [CODE]; [POST_ITERATION_ACTION]; }
      

       

      如果您正在考虑将一堆 if 语句合并为一个:不要,您不会得到任何好处。 PHP 会进行短路,这意味着如果它达到了它知道结果会是什么的程度,它将跳过其余部分。

      例如,考虑$a = 5; if ($a &gt; 0 || $b &gt; 100 || $c &gt; 200) {}
      一旦 PHP 发现 $a &gt; 0 条件得到满足,整个语句就会解析为 true(因为使用了 OR 值)并且不会费心检查 $b &gt; 100$c &gt; 200

      所以回答您的问题:除非您有大量的条件,每个条件都需要复杂的计算或有副作用,您通常可以认为它们的数量无关紧要。
      但是,正如其他人所指出的那样,使用过多的 if 语句会降低代码的可读性。在许多情况下,如果您可以删除条件而不影响代码的行为,那么您一开始就不需要它。

      【讨论】:

        【解决方案4】:

        问题不在于是否有太多 if else 语句,而是 1)它们的顺序和 2)您的条件有多有效

        1) If else 状态应按条件概率的降序排列。 在我特定的wp_posts 数据库表中,80% 的记录有post_status 的“草稿”、“待定”、“垃圾”等,但没有“发布”。大约 40% 的记录将“发布”为post_type。所以,没有意义

        if ($post_type=="post"&&$post_status=="publish") {
            doA();
        } elseif ($post_type!="post"&&post_status=="publish") {
            doB():
        } elseif ($post_type=="post"&&post_status!="publish") {
            doC();
        } else {
            doD();
        }
        

        但它应该是相反的顺序

        关于 2),WordPress 的数据库架构表明 in_category() 会很慢。如果是您自己编写的查询,当然,这取决于您的查询效率如何

        【讨论】:

          【解决方案5】:

          If 子句是一些最便宜的操作,就性能而言。

          然而,你在 if 子句中放入 的内容可能真的很慢。

          例如,if (true) { ... } 将非常快,但单个 if (calculatePi()) { ... } 将永远持续下去。 if 本身是如此之快,以至于您永远不必担心它,此外,您所做的几乎所有其他事情都涉及到许多 ifs,例如当您执行 forwhile 时循环或switch 语句。所有这些本质上都包含if(一个或多个)。

          至于设计,很多ifs 可能会让其他开发人员感到困惑,这取决于您编写的内容和编写方式。有时您最好使用 switch/case 语句或其他一些应用程序工作流程,但说实话,一堆ifs 可能会比您可能想出的任何类型的结构执行得更快。但是,如果您唯一关心的是性能,请记住这一点。设计软件不是,我重复一遍,不是主要是关于性能。良好的软件设计与可维护性等其他方面有关,即阅读和成功升级代码的难易程度。

          简而言之,如果您正在优化性能,请不要费心尝试减少 ifs 的数量。而是关注ifs 所询问的内容,或者取决于他们返回真假会发生什么。

          希望对你有帮助。

          【讨论】:

            【解决方案6】:

            在大多数情况下,非常复杂的 if/else 结构表明设计不佳。你可以更好地专注于改进一个糟糕的设计而不是优化,premature optimization is the root of all evil!

            如果你给出你所谈论的代码类型的例子,也许可以给出更详细的答案。

            【讨论】:

            • 我对 Wordpress 不是很熟悉,所以我不知道这些功能实际上是做什么的,也不知道你想用这个页面实现什么。我假设您正在创建模板,但也许您可以创建另一个问题以获得最佳方法。至于 if/else 语句,您正在制作 if/else/else 结构,这很好,但性能将取决于 Wordpress 函数所做的工作。很多数据库查找对性能不利,但简单的数组查找不应该对性能造成太大影响。
            • 好的,谢谢你的建议。我试图在某些页面上包含社交按钮,并为每个模板文件以不同的方式实现它们。因此,如果它是帖子,它会显示一种类型,如果它是页面,它会显示另一种......
            • 好的,在这种情况下,我不认为这些 if/else 语句有问题。我假设 Wordpress 会从数据库中检索一次页面类型,并且您调用的函数会使用此检索到的结果。但请注意,这只是我的猜测。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2022-08-06
            • 2012-04-25
            • 1970-01-01
            • 2013-05-25
            • 2022-11-29
            • 1970-01-01
            • 2021-09-08
            相关资源
            最近更新 更多