1

After profiling a PHP script, I found that creating an exception appears to take a huge amount of time:

%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

So that's 7.5 seconds of real (not CPU) time per ErrorException->__construct. I'm looking for ideas on how to improve this!

Relevant code:

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;
  }
}

Even if there's no obvious answer, I'd like to understand what factors could influence the real time to be so large. My understanding is that the constructor doesn't include time for the file_get_contents call itself or the catch clause, so can't really think of a good reason (other than trying to allocate a huge amount of memory) why this should be slow.

4

2 回答 2

0

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

因此,我相信高耗用时间是因为分析器实际上包括从file_get_contents.

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

于 2013-09-14T02:22:07.287 回答
0

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

于 2013-09-08T09:43:43.073 回答