我想知道我的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"
}
//
?>
答案 0 :(得分:13)
不。事实上,在大多数情况下它实际上会加速它(因为它允许跳过代码块)。
只有当您检查的条件需要处理时,大量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 > 0 || $b > 100 || $c > 200) {}
一旦PHP看到满足$a > 0
条件,整个语句就会解析为true(因为使用了OR值),并且无需检查$b > 100
或$c > 200
。
所以回答你的问题:除非你有一些不合格的条件,每个条件都需要复杂的计算或有副作用,你通常可以认为它们的数量是无关紧要的。
但是,正如其他人所指出的那样,if语句太多会降低代码的可读性。在许多情况下,如果您可以删除条件而不影响代码的行为,那么您不需要它开始。
答案 1 :(得分:5)
if-clauses是一些最便宜的操作,性能方面。
然而,你把放在 if子句中的内容可能非常慢。
例如,if (true) { ... }
的速度非常快,但单个if (calculatePi()) { ... }
将永远占据一席之地。 if
本身是如此之快,以至于你永远不必担心它,此外,你所做的其他事情无论如何都涉及到许多if
,例如当你做{{1}时}或for
循环或while
语句。所有这些本质上都包含switch
(一个或多个)。
至于设计,很多if
可能会让其他开发人员感到困惑,这取决于你写的是什么以及它是如何编写的。有时候你最好使用switch / case语句或其他一些应用程序工作流程,但是说实话,一堆if
可能比你想出的任何结构都要快。但是,如果您的唯一关注点是性能,那么只能牢记这一点。设计软件不,我再说一遍,不主要是关于性能。良好的软件设计与其他方面有关,例如可维护性,即读取和成功升级代码的容易程度。
简而言之,如果您正在优化性能,请不要试图减少if
的数量。而是关注if
s所询问的内容,或者根据它们是返回真还是假而发生的事情。
希望它有所帮助。
答案 2 :(得分:4)
我刚刚从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!';
示例说明
上面两个代码片段之间的区别归结为一个关键的区别:
冒泡方法询问重要条件是否为真,并且只有在它们为真时运行代码。
网关方法询问重要条件是否为假,并在每个条件为假时立即发出退出说明。
冒泡方法会强制嵌套,因为在到达要运行的代码之前,必须先检查“true,true,true,true”。每个“true”检查都是一个嵌套级别 - 您的代码必须存在的条件。
网关方法未嵌套:
如你所见,代码永远不会超过一层逻辑层。这是因为一旦给定网关通过,我们就可以完全忘记它。换句话说,由于我们在$is_first_thing_working
检查后未退出,因此我们会自动知道其余代码$is_first_thing_working
为真。
“这就像现实生活:如果你在历史课上坐在我旁边,我 知道你是一个人,一个在我高中的学生,等等 - 或者你 从来没有在我的班上。无需检查。“
答案 3 :(得分:3)
非常复杂的if / else结构在大多数情况下表明设计不好。您可以更好地专注于改进糟糕的设计,而不是优化premature optimization is the root of all evil!。
如果您举例说明您所谈论的代码类型,则可能会给出更详细的答案。
答案 4 :(得分:0)
问题不在于有太多if else语句,而是1)它们的顺序和2)你的条件有多高效
1)如果其他状态应按条件概率的降序排列。
在我的特定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 :(得分:0)
在某种程度上...... 是
我说这是考虑最坏的情况,在这种情况下是一个非常大的模型对象,有很多条件。在这里,代码必须经历所有条件检查,最终减慢代码。
条件语句对并行化和向量化造成困难,并且一长串IF-THEN也可能导致指令高速缓存未命中和其他影响。但如果这是使代码最清晰的原因,那么就使用它。