有可能告诉php解释器忽略代码块吗?

时间:2015-06-04 19:25:16

标签: php interpreter opcache

背景

在我进行C编程的那天,我们使用了假设语句来确保代码是健康的。类似的东西:

aFunction(int hello)
{
  assume(hello < 10);

关于assume语句的一个很酷的事情是它被定义为发布编译的空宏和调试编译时的假语句。因此,开发人员拥有断言语句的所有好处,可以检查他们的假设,而不会导致不必要的错误或影响

中的性能

问题

现在我正在使用php我正在寻找类似的机制。我目前的假设声明看起来像这样:

define(DEBUG, getenv('debug'));
function assume($a)
{
  if (DEBUG && !$a)
  {
    echo 'ASSUME FAILURE <br />';
    echo '<pre>';
    print_r(debug_backtrace());
    die('<pre>');
  }
}
assume($a == $b);

如您所见,我在服务器设置中设置了调试标志,以删除实际的die语句等。但是仍然执行函数调用,仍然会评估if语句。如果它只发生几千次,这并不是什么大问题,但随着代码变得越来越大,并且这些假设被置于循环中,这可能会对性能产生合理的影响。

问题

有没有办法告诉解释器或opcache(我目前正在使用php 5.5中包含的zend opcache)完全忽略这些假设语句?还是有其他方法来处理这个问题?

1 个答案:

答案 0 :(得分:5)

不同之处在于C编译器已经过优化,可以消除未使用的代码块。在PHP中,assume是函数调用,函数必须存在。

一些解决方案。首先,您可以使用assert()assert函数与您自己的assume函数类似。如果断言失败,则调用定义的断言处理程序。您可以轻松启用或禁用断言,如果禁用断言,则根本不会调用断言处理程序。

如果您想继续使用自己的assume函数,您仍然可以通过根据define声明函数来稍微优化它:

<?php
define(DEBUG, getenv('debug'));

if (DEBUG) {
  function assume($a) {
    echo 'ASSUME FAILURE <br />';
    echo '<pre>';
    echo print_r(debug_backtrace());
    die('<pre>');
  }
} else {
  function assume($x) {}
}

这样,您实际上将assume声明为空函数。 Michael Berkowski的评论证实了我担心PHP不会完全消除掉这个电话,但至少你保存了if

另一个解决方案是调用假设更复杂:

DEBUG && assume($x < 10);

这样,如果DEBUG为false,则根本不会进行调用。这样只评估布尔值,并且不进行函数调用。当然,以这种方式调用它有点难度和可读性,但我认为不调用函数的节省比消除if更重要。