for、while、foreach性能比较
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了for、while、foreach性能比较相关的知识,希望对你有一定的参考价值。
参考技术A 1、当数组长度未知时(需要再循环前count计算数组长度):for和while循环效率基本持平,foreach是最快的。2、当数组长度已知时(在循环中直接写循环次数):for和while循环效率基本持平,foreach是最慢的。
PHP - If/else, for, foreach, while - 没有花括号?
【中文标题】PHP - If/else, for, foreach, while - 没有花括号?【英文标题】:PHP - If/else, for, foreach, while - without curly braces? 【发布时间】:2012-02-02 07:45:37 【问题描述】:真正想知道但从未发现的东西是 PHP 中的快捷方式。
我目前正在编写一个带有foreach
循环的函数,其中只有一个语句。我试图省略花括号,就像在 if/else 控制结构中可以做的那样,它可以工作。没有错误。
foreach($var as $value)
$arr[] = $value;
现在我尝试以相同的方式使用它,但在其中放置了一个 if/else 块。再次,正常工作,没有错误。
foreach($var as $value)
if(1 + 1 == 2)
$arr[] = $value;
;
然后,我想“为什么会这样?”并省略了结束分号。还在工作。因此,我尝试在 foreach 循环中使用不带花括号的 if/else 语句,并且再次使用,仍然有效且没有错误。但是 foreach 循环现在真的关闭/结束了吗?
foreach($var as $value)
if(1 + 1 == 2)
$arr[] = $value;
至少我再次省略了结束分号,并且(如预期的那样)发生了解析错误。
所以我的大问题是:我什么时候可以省略花括号以及在哪个结构/循环/函数中?我知道我绝对可以在if
和else
中这样做。但是while
、for
和foreach
呢?
是的,我知道它不安全、不聪明,无论在没有花括号的情况下进行编码,还有像 $condition ? true : false;
和 if: doSomething(); endif;
、endfor;
和 endforeach;
这样的速记。我不想学习速记我只想了解何时何地可以省略大括号的条件。
【问题讨论】:
顺便说一下,没有必要在右大括号后放置分号。 this 的句法含义是在它们之间添加一个空语句。除了在 C 和 C++ 中声明struct
和 class
之外,所有类 C 语言都是如此。
您需要了解语句和表达式之间的区别才能了解何时可以省略大括号。然后仍然需要对表达凝聚力有深刻的理解。
【参考方案1】:
当你省略大括号时,它只会将下一条语句视为条件的主体。
if ($x) echo 'foo';
与
相同if ($x) echo 'foo';
但请记住
if ($x)
echo 'foo';
echo 'bar';
将总是打印“bar”
在内部则相反:if
只会查看下一个表达式,但 PHP 将 中的所有内容视为单个“分组”表达式。
其他控制语句也一样(foreach
,等等)
【讨论】:
非常好的简短解释,谢谢! :) 它适用于每个控制结构吗? 应该的。目前不知道(也无法测试)dowhile($X);
或“开关”是什么。
@headacheCoder 是的,它适用于for
、while
、foreach
和if
。对于每种具有类 C 语法的语言也是如此。请注意@tkone 的回答,关于始终使用大括号的良好做法。
@headacheCoder:它甚至适用于每个表达式,请参阅php.net/expressions。
有一个例外;它不适用于Exceptions。双关语完全是故意的。【参考方案2】:
有些地方你可以,但你永远不应该。
显式总是优于隐式。
谁知道你什么时候必须回去修改旧代码。很容易错过这些东西,而且这样做没有任何收获。
【讨论】:
【参考方案3】:如果你里面只有一个参数,它会工作得很好!。但是如果你想省略花括号,你可以使用冒号和结尾。 示例:
if(a < 1 ) :
echo "a is less than 1";
else :
echo "a is greater than 1";
endif;
【讨论】:
【参考方案4】:如前所述,您不想了解速记,并且接受的答案给出了省略curly braces
的好例子,但还有一些东西要补充。如您所见,在if ($x) echo 'foo';
的情况下省略curly braces
很好。代码没有问题,没有性能或其他问题,其他开发人员可以阅读。并且示例还向您展示了,如果您编写
if ($x)
echo 'foo';
echo 'bar';
而不是
if ($x)
echo 'foo';
echo 'bar';
您可能会遇到不需要的结果,其中打印了 bar
而您不希望它被打印,如果您的代码中充满了此类语句,那么您将更难阅读自己的代码,甚至更多其他人更难阅读。
我不想了解速记,我只想了解何时何地可以省略大括号的条件。
这些东西是密切相关的,所以如果你真的想了解可以省略大括号的地方,那么你应该了解或至少知道速记,阅读过
-
PHP Control Structures
The PHP ternary conditional operators and expressions in general
所以我的大问题是:我什么时候可以省略花括号以及在哪个结构/循环/功能中?
花括号不是必需的,但是为了可读性和维护,许多开发人员会认为不包含它们是不好的风格。当您可以省略花括号时,前 2 个链接应为您提供做出自己决定所需的信息。 例如,下面的代码 sn-ps 没有任何问题,它们都做同样的事情。
带花括号
if (PHP_VERSION_ID < 70000)
print "PHP >= 7.0 required yours is ";
print phpversion();
print "\n";
exit(1);
同
if (PHP_VERSION_ID < 70000) :
print "PHP >= 7.0 required yours is ";
print phpversion();
print "\n";
exit(1);
endif;
或者你可以使用点运算符
if (PHP_VERSION_ID < 80000)
(print "PHP >= 7.0 required yours is ") . (print phpversion()) . (print "\n") . exit(1);
你可以使用三元条件运算符,甚至可以省略if
它自己,除了省略花括号
(PHP_VERSION_ID > 70000) ?: (print "PHP >= 7.0 required yours is ") . (print phpversion()) . (print "\n") . exit(1);
由于我们只打印,我们可以缩短它并去掉一些 print string functions
,它们在这里表示语句中不带花括号的多个函数
(PHP_VERSION_ID > 70000) ?: (print "PHP >= 7.0 required yours is " . phpversion() . "\n") . exit(1);
从 php 7 开始,我们可以使用 Null 合并运算符
(PHP_VERSION_ID > 70000) ?: null ?? (print "PHP >= 7.0 required yours is ".phpversion() . "\n") . exit(1);
可以看出,有很多方法可以获得完全相同的结果。这不仅适用于这个if
示例,而且同样适用于structure/loop/function
。所以对于您的大问题,没有一个答案。应该主要考虑以下。
-
您编写的代码是否易于维护。
您能自己回答一下,您是否可以通过省略花括号来赢得一些东西。
【讨论】:
嗯,我不知道他们在 Elvis 运算符中添加了一个空合并运算符……很整洁。但是运算符的哪一侧为空,它是否允许在条件块中未设置变量?$I_want_value = $if_im_not_null_use_me ?? $if_first_is_null_use_me ?? $if_second_is_null_use_me;
因此,如果先前的变量为 NULL,您可以有尽可能多的选择; PHP 7 New-features
有趣,所以它是一个无限运算符......但它是否适用于未定义的变量?我会检查文档。我认为这是拥有空合并运算符的唯一目的,否则为什么不直接使用 Elvis。 ?:)
啊,是吗?确实适用于未设置的变量,文档说。精彩的!这可能会减少 PHP 中 isset() 调用的大量麻烦。【参考方案5】:
我在我的 PHP 模板中省略了花括号。例如。您可以按如下方式使用循环:
<ul>
<?php foreach ($var as $value): ?>
<li><?php echo $value; ?></li>
<?php endforeach; ?>
</ul>
【讨论】:
替代语法有所不同。 OP 甚至说他知道替代语法,而不是问题所在。【参考方案6】:您可以将它用于简单的事情,例如:
if($a === true) continue;
但对于一些更复杂的子条件,它可能会给你带来问题:
$a = false;
$b = false;
if ($a === true)
if ($b === true)
echo 1;
else
echo 2;
使用上面的代码,您希望看到“2”作为输出,但您不会。
【讨论】:
【参考方案7】:为了补充@Marko的答案,请注意,在使用点运算符时,您应该将每个操作括在括号中,否则会颠倒顺序。
例如,下面这段代码将打印PHP >= 7.0 required yours is 5.6.15
。
(print "PHP >= 7.0 required yours is ") . (print phpversion()) . (print "\n");
虽然这将打印5.6.151PHP >= 7.0 required yours is 1
。
print("PHP >= 7.0 required yours is ") . print(phpversion()) . print("\n");
您也可以使用and
运算符来实现此目的。像这样:
if (PHP_VERSION_ID < 70000)
print("PHP >= 7.0 required yours is ") and
print(phpversion()) and
print("\n");
【讨论】:
【参考方案8】:对于单行语句。
如果你尝试这样做
foreach($array as $x => $y)
$do_something = $x;
$do_something_else = $y;
除非我弄错了,否则 php 解释器会将 foreach 语句下的第二行视为隐含大括号之外
由于缩进,如果您稍后返回此代码,或者其他开发人员查看您的工作,这会令人困惑。
因此,在这些语句中始终使用大括号通常是明智的。它将避免以后的头痛/困惑
【讨论】:
你是对的。第二行不在循环内。只有下一个表达式是。【参考方案9】:当您的子句后只有一个表达式时,这是可能的/
例如,
foreach($var as $value)
if(1 + 1 == 2)
$arr[] = $value;
;
是正确的,但是
foreach($var as $value)
$somevar = $var;
if(1 + 1 == 2)
$arr[] = $value;
;
不是,php解释器会认为if
语句在foreach
之外
【讨论】:
【参考方案10】:答案很简单。在 C/C++ 中也是如此。
if, if/else, if/else if/else and loops => 如果下一条语句是单行,你可以省略花括号。
例如:
for($i= 0; $i<=100; $i++)
if($i % 7 == 0)
echo $i . "<br>";
也可以这样写:
for($i= 0; $i<=100; $i++) if($i % 7 == 0) echo $i . "<br>";
【讨论】:
【参考方案11】:我什么时候可以省略花括号以及在哪个结构/循环/功能中? 我知道我绝对可以在 if 和 else 中这样做。但是关于 while、for 和 foreach?
对于 If/else,通过使用以下构造,可以使 single 和 multiple statements 不带花括号:
<?php
if ($x):
echo 'foo';
echo 'bar';
else:
echo 'nofoo';
echo 'nobar';
endif;
?>
如this answer中所述
对于while、for和foreach,只允许单个语句不带大括号
<?php
foreach($array as $x => $y)
$do_something = $x;
?>
【讨论】:
【参考方案12】:PHP 速记表达式从 PHP 5.3 开始提供
$condition ? $value_if_true : $value_if_false
$a ? $b : ( $c ? $d : ( $e ? $f : $g ) )
【讨论】:
以上是关于for、while、foreach性能比较的主要内容,如果未能解决你的问题,请参考以下文章