我用来导致这个问题的代码太大了,不能在这里发布,问题很奇怪,我无法重新创建一个具有相同问题的小例子。我有一些看起来像这样的代码:
<?php
class A {
//Lots of methods
public function fastMethod($id) {
return 0;
}
public function differentFastMethod($id) {
$this->someOtherObject->someOtherFastMethod();
return $this->fastMethod($id);
}
public function slowMethod() {
$c = 0;
$start = microtime(true);
// hugeList has about 100,000 ids.
foreach ($this->hugeList as $id) {
// bigLookupTable has an array for almost all ids, each array contains one or two items.
if (isset($this->bigLookupTable[$id]) {
foreach ($this->bigLookupTable[$id] as $differentId) {
fastMethod($diferentId);
$c++;
}
}
}
$end = microtime(true);
print $end - $start;
}
}
?>
运行slowMethod
大约需要1秒钟,但如果我删除对fastMethod
的调用,则大约需要0.1秒。我认为这只是一个很大的函数调用开销,但还有更多的东西。
例如,如果我将fastMethod
的调用更改为differentFastMethod
,则需要大约相同的时间,即使这不仅会向此对象添加更多函数调用,而且还会向其他对象添加一些调用对象。此外,如果我在内部循环中向fastMethod
添加更多调用,则每个调用仅增加大约0.1秒的时间。看起来这个循环需要额外的一秒才能根据它是否自己调用实例方法来运行,无论这些方法做什么,无论有多少。
关于性能的另一个有趣的事情是slowMethod
中的内部循环。传递给它的数组大多是1个元素长或偶尔2个元素,因此取出循环并在数组的第一项上调用fastMethod
应该快得多,但这实际上要快得多,加速它与删除fastMethod
的呼叫大约相同的数量。
我意识到如果没有一个有效的例子就很难诊断出来,但是如果有人有任何想法我可以在实际代码上测试它,我很难理解这可能导致这样的行为。