【问题标题】:Why is a function re-definition faster than calling the first one?为什么重新定义函数比调用第一个函数更快?
【发布时间】:2012-01-27 15:18:37
【问题描述】:

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

简化示例:

$javascriptCode = file_get_contents($filename);
$funcName = 'func'.md5($filename);
$v8js->executeString("
 function {$funcName} () {
  {$javascriptCode}
 }");
$v8js->executeString("var testVariable = {$funcName}();");

~50 次调用 = 200 毫秒

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

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 次调用 = 900 毫秒

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

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

为了验证缺少的重新定义是性能损失的唯一原因,我更改了 if:

if ( !isset($this->cache[$filename]) || true ) {

... 函数名仍然保存到数组中,排除 php-array 作为可能的问题。

巨大的性能损失来自哪里,或者我该如何进一步调试?

【问题讨论】:

    标签: php javascript performance v8


    【解决方案1】:

    我创建了几个测试来进一步识别所有内容,最后发现隐藏在我自己的 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)
    

    【讨论】:

      猜你喜欢
      • 2014-05-19
      • 1970-01-01
      • 1970-01-01
      • 2014-12-30
      • 1970-01-01
      • 2022-01-09
      • 2011-04-30
      • 2012-06-02
      • 2013-03-14
      相关资源
      最近更新 更多