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;

至少我再次省略了结束分号,并且(如预期的那样)发生了解析错误。

所以我的大问题是:我什么时候可以省略花括号以及在哪个结构/循环/函数中?我知道我绝对可以在ifelse 中这样做。但是whileforforeach 呢?

是的,我知道它不安全、不聪明,无论在没有花括号的情况下进行编码,还有像 $condition ? true : false;if: doSomething(); endif;endfor;endforeach; 这样的速记。我不想学习速记我只想了解何时何地可以省略大括号的条件。

【问题讨论】:

顺便说一下,没有必要在右大括号后放置分号。 this 的句法含义是在它们之间添加一个空语句。除了在 C 和 C++ 中声明 structclass 之外,所有类 C 语言都是如此。 您需要了解语句和表达式之间的区别才能了解何时可以省略大括号。然后仍然需要对表达凝聚力有深刻的理解。 【参考方案1】:

当你省略大括号时,它只会将下一条语句视为条件的主体。

if ($x) echo 'foo';

相同
if ($x)  echo 'foo'; 

但请记住

if ($x)
  echo 'foo';
  echo 'bar';

总是打印“bar”

在内部则相反:if 只会查看下一个表达式,但 PHP 将 中的所有内容视为单个“分组”表达式。

其他控制语句也一样(foreach,等等)

【讨论】:

非常好的简短解释,谢谢! :) 它适用于每个控制结构吗? 应该的。目前不知道(也无法测试)dowhile($X); 或“开关”是什么。 @headacheCoder 是的,它适用于forwhileforeachif。对于每种具有类 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 &gt;= 7.0 required yours is 5.6.15

(print "PHP >= 7.0 required yours is ") . (print phpversion()) . (print "\n");

虽然这将打印5.6.151PHP &gt;= 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,通过使用以下构造,可以使 singlemultiple statements 不带花括号:

<?php
  if ($x):
    echo 'foo';
    echo 'bar';
  else:
    echo 'nofoo';
    echo 'nobar';
  endif;
?>

如this answer中所述

对于whileforforeach,只允许单个语句不带大括号

<?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性能比较的主要内容,如果未能解决你的问题,请参考以下文章

for、forEach、map的性能对比

JavaScript 循环性能比较

for循环与forEach性能思考

map,foreach和for的使用

高性能JavaScript 循环语句和流程控制

web性能优化--算法优化