Php 为什么重新定义函数比调用第一个函数快?

Php 为什么重新定义函数比调用第一个函数快?,php,javascript,performance,v8,Php,Javascript,Performance,V8,我正在用php阅读javascript文件,并使用v8js执行它们 简化示例: $javascriptCode = file_get_contents($filename); $funcName = 'func'.md5($filename); $v8js->executeString(" function {$funcName} () { {$javascriptCode} }"); $v8js->executeString("var testVariable = {$fu

我正在用php阅读javascript文件,并使用v8js执行它们

简化示例:

$javascriptCode = file_get_contents($filename);
$funcName = 'func'.md5($filename);
$v8js->executeString("
 function {$funcName} () {
  {$javascriptCode}
 }");
$v8js->executeString("var testVariable = {$funcName}();");
~50次呼叫=200ms

为了提高性能,我将后续调用减少为仅在函数已定义时调用函数名:

if ( !isset($this->cache[$filename]) ) {
 $javascriptCode = file_get_contents($filename);
 $funcName = 'func'.md5($filename);
 $v8js->executeString("
  function {$funcName} () {
   {$javascriptCode}
  }");
  $this->cache[$filename] = $funcName;
}
else {
 $funcName = $this->cache[$filename];
}
$v8js->executeString("var testVariable = {$funcName}();");
~50次呼叫=900ms

由于某些原因,这比重新运行函数定义(第一个代码部分)要慢

我调用了几十个javascript文件和函数,使用第一个代码示例,它们都在200毫秒内运行。在为已经定义的函数名添加缓存并且不再重新定义它们之后,完全相同的代码的运行时间大约为900ms

为了验证丢失的重新定义是否是性能损失的唯一原因,我更改了以下条件:

if ( !isset($this->cache[$filename]) || true ) {
…函数名仍保存到数组中,排除php数组是一个可能的问题


巨大的性能损失是从哪里来的?我如何进一步调试它?

我创建了几个测试来进一步识别所有内容,最终找到了隐藏在我自己的javascript代码深处的原因

即使代码是相同的,javascript中的一些
if
也决定横向执行,并使所有操作都变慢:-)

下面是我做的上一次测试的源代码,该测试表明,如果没有重新定义,它会像预期的那样更快:

<?php
$runList = array(10, 100, 1000, 10000, 100000);
$jsFunc = 'function myTestFunc () { return {foo: "bar"}; } ';
foreach ($runList as $runs ) {

    $start = mstime();
    $js = new V8Js('Test');
    for ( $i = $runs; $i > 0; $i-- ) {
        $js->executeString($jsFunc, 'Test.Context');
        $js->executeString("myTestFunc();", 'Test.Context');
    }
    echo "#1: " . (mstime() - $start)." ({$runs} with re-definition)<br />";
    unset($js);

    $start = mstime();
    $js = new V8Js('Test');
    $js->executeString($jsFunc, 'Test.Context');
    for ( $i = $runs; $i > 0; $i-- ) {
        $js->executeString("myTestFunc();", 'Test.Context');
    }
    echo "#2: " . (mstime() - $start)." ({$runs} without re-definition)<br />";
    unset($js);
    echo "<hr />";
}

function mstime() {
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}
#1: 0.000640869140625 (10 with re-definition)
#2: 0.0003800392150878906 (10 without re-definition)
#1: 0.001749992370605469 (100 with re-definition)
#2: 0.0009560585021972656 (100 without re-definition)
#1: 0.01554703712463379 (1000 with re-definition)
#2: 0.04881501197814941 (1000 without re-definition)
#1: 0.503957986831665 (10000 with re-definition)
#2: 0.1761679649353027 (10000 without re-definition)
#1: 4.813416957855225 (100000 with re-definition)
#2: 1.93553900718689 (100000 without re-definition)