PHP ErrorException创建需要很长时间

时间:2013-09-08 09:28:27

标签: php exception exception-handling error-handling

在分析PHP脚本之后,我发现创建异常似乎需要花费大量时间:

%Time            Real      User    System Calls         secs/call  Name
100.0    0.00 3448.05 0.00 8.89 0.00 1.81     1  0.0000 3448.0543  main
 64.7 2230.28 2230.28 0.02 0.02 0.00 0.00   892  2.5003    2.5003  sleep
 35.1    0.01 1211.84 0.00 8.16 0.00 1.49  1001  0.0000    1.2106  do_process
 34.7  986.81 1197.34 2.59 2.60 1.18 1.18  1330  0.7420    0.9003  file_get_contents
  6.1    0.00  210.53 0.00 0.01 0.00 0.01    28  0.0000    7.5191  __lambda_func
  6.1  210.53  210.53 0.01 0.01 0.01 0.01    28  7.5191    7.5191  ErrorException->__construct
  0.4    0.00   13.47 0.01 5.21 0.00 0.18   206  0.0000    0.0654  do_check
  0.4   13.15   13.15 5.08 5.08 0.15 0.15   402  0.0327    0.0327  preg_replace

这样每ErrorException->__construct的实时(非CPU)时间为7.5秒。 我正在寻找有关如何改善这一点的想法!

相关代码:

set_error_handler(
  create_function(
    '$severity, $message, $file, $line',
    'throw new ErrorException($message, $severity, $severity, $file, $line);'
  )
);

$opts = array(
  'http' => array(
    'method'  => 'GET',
    'timeout' => 60
  )
);
$ctx = stream_context_create($opts);
try {
  $this->data = file_get_contents($url, false, $ctx);
} catch (Exception $e) {
  # The set_error_handler call ensures that we arrive here on any type
  # of error.
  $this->data = '';
  if(preg_match('/HTTP\/1.[0|1] 4[0-9][0-9] /', $e->getMessage()) == 1) {
    return 404;
  } else if(strpos($e->getMessage(), "php_network_getaddresses: getaddrinfo failed") !== false) {
    return 1000;
  } else {
    $this->message = $e->getMessage();
    return -1;
  }
}

即使没有明显的答案,我也想了解哪些因素会影响如此大的实时。我的理解是,构造函数没有包含file_get_contents调用本身或catch子句的时间,因此无法真正想到一个充分的理由(除了尝试分配一个大量内存)为什么这应该很慢。

2 个答案:

答案 0 :(得分:0)

您正在使用通过调用create_function()创建的oldschool lambda函数。是否有一个原因?因为函数的运行方式很慢。您使用函数的代码传递STRING,但必须在运行时评估该字符串。操作码缓存无法为您缓存该代码。

答案 1 :(得分:0)

经过相当多的测试后,问题似乎在于APD剖析如何测量经过的时间。如果我在throw之前将任何其他语句放在错误处理程序中,则探查器将计算所有已用时间,如我的评论中所述。

因此,我确信经过的时间很长,因为探查器实际上包括file_get_contents的经过时间。

我尝试使用XHProf,这似乎给出了更正确的结果。至少,它显示ErrorException->__construct只占用最少的时间。