【问题标题】:php / apache2 - shorthand if (bug - discussion, finding an explanation)php / apache2 - if 的简写(bug - 讨论,找到解释)
【发布时间】:2013-11-05 13:48:29
【问题描述】:

这是我无法解释的非常奇怪的事情,但可能你们中的一些人已经发现了相同或类似的问题?

想象一下下面的伪 PHP 代码:

<?PHP

  mysql_connect("localhost", "mysql_user", "mysql_password");
  mysql_select_db("mydb");
  $result = mysql_query("SELECT id, my_name FROM my_table");

  while ($row = mysql_fetch_array($result, MYSQL_NUM)) {

      $row[1] ? echo $row[1] : echo $row[0];

  } 

  mysql_free_result($result);

?>

这基本上只是查询 mySQL 服务器并遍历所有记录集。 然后,它使用“速记”if 语句来查明my_name 列中是否有内容。如果有,它将打印它,如果没有,它将打印id

现在奇怪的部分是,在 Debian Linux 虚拟机上,在 ESX5 上运行这个简写 if 比普通的 if{}else{} 语句要长 10 倍。

所以在我的例子中不是 3 秒(迭代 5000 条记录),而是在这个特定的 VM 上需要 30 秒 - ESX4 Debian 主机上的相同代码运行得很好。

如果我用普通的 IF 语句替换速记 IF,一切都很好。

我在互联网上做了一些研究,但找不到解释。 您将从哪里开始搜索问题?

谢谢! // 马库斯

【问题讨论】:

  • 只是好奇,但是如果您使用 echo $row[1] ,速度比较是多少? $row[1] : $row[0];
  • 开始测试...从等式中消除 mysql。构建一个结果数组,然后在数组上循环,这样就不会调用 mysql。
  • 进行测试 ^^ 上百万次尝试以正确平均速度。
  • 确实应该是:echo ($row[1] ? $row[1] : $row[0]);在 ?非常奇怪。
  • 哦,它真的应该是echo ($row[1] ? $row[1] : $row[0]) - 我将重新运行测试,看看这是否会有所不同。 (rtfm :))

标签: php linux performance apache virtual-machine


【解决方案1】:

好吧,我的错 - 我应该先阅读有关三元运算符的手册,然后再“疯狂”使用它们...

我将运算符更改为正确的格式,如 cmets 中提到的 Acyclic TauMTilsted

$output .= ($row[1] ? $row[1] : $row[0]);

奇怪的速度问题消失了——但下一个问题是为什么 PHP 没有因为语法错误而抛出异常?

【讨论】:

  • 因为它实际上没有语法错误。正在执行语句“echo $row[1]”并将其评估为一个值,然后将其临时复制。此评估的一个副产品是您的脚本确实回显了所需的结果。
  • 其实我并不完全确定我上面的陈述是否正确,echo 不是一个函数而是一种语言结构,所以虽然它会被评估为 void,但它可能在语法上被认为是不正确的。也许其他人可以提供一个明确的答案。
  • 有趣的阅读:stackoverflow-2698372 - OP 确实收到了意外的 T_ECHO 错误,而我没有。顺便说一句,我在 PHP 5.3.3-7
  • 好的,做了一些测试——当我写“伪”代码时,我在三元运算符中使用了 echo——这实际上抛出了一个“意外的 T_ECHO”——但在真正的代码中我使用了像这样的变量:$row[1] ? $output .= $row[1] : $output .= $row[0]; - 如果您以这种方式使用三元运算符,它不会引发任何期望 - 但是语法错误。
【解决方案2】:

我相信三元运算符 (?) 和 IF 语句之间存在根本区别(如此处所述http://fabien.potencier.org/article/48/the-php-ternary-operator-fast-or-not),总和基本上是:

三元运算符的速度与复制语句结果所需的时间直接相关,即使不是严格需要也是如此。并且复制一个包含 100000 个元素的数组需要时间。

这是因为三元运算符将值复制到新的内存位置,而 if..else 块可能不会。

虽然这可以解释单个虚拟机实例的速度差异,但它并不能充分解释为什么两个虚拟机都使用三元运算符时速度不同。 假设您使用的两个虚拟机位于不同的硬件上。您是否有可能使用不同版本的 PHP?两台主机的底层处理器不同,是否影响了内存副本的处理速度?

【讨论】:

  • 很好的研究,谢谢;是的,这两个虚拟机具有不同的物理 CPU 和硬件——它们都运行着完全相同的服务器虚拟映像,所以 PHP 版本是相同的。有趣的是,如果我在运行循环时 strace apache 进程,您会看到很多 mmap2(NULL) 调用。
猜你喜欢
  • 2014-09-11
  • 1970-01-01
  • 1970-01-01
  • 2013-11-19
  • 1970-01-01
  • 1970-01-01
  • 2011-04-21
  • 1970-01-01
  • 2016-12-25
相关资源
最近更新 更多