【问题标题】:Memory consumption on an iteration script迭代脚本的内存消耗
【发布时间】:2012-12-28 12:00:41
【问题描述】:

我有一个用 PHP 编写的脚本和用 Javascript 编写的相同脚本。
它迭代一百万次,每次都将一个字符串剥离到一个数组中,并将第一个数组项分配给一个新变量。

PHP 是:

class First
{
public function Iterate()
{
    $count = 1000000; 
    $test_string = '';
    $test_array = '';
    $first_word = '';
    for($i=1; $i <= $count; $i++){
        $test_string = 'This is a test string';
        //could use explode but no explode in js
        $test_array = split(" ", $test_string);
        $first_word = $test_array[0];
    }
}
}
$first = new First();
$first->Iterate();

而 Javascript 是:

function First() {
this.Iterate = function() {
    count = 1000000;
    test_string = '';
    test_array = '';
    first_word = '';
    for(var i=1;i <= count; i++){
                    test_string = 'This is a test string';
                    test_array = test_string.split(" ");
                    first_word = test_array[0];
    }
}
}
first = new First();
first.Iterate();

我使用 PHP-CLI 5.3.10 运行 PHP,使用节点 v0.6.12 运行 Javascript。

对于 PHP,我使用“memory_get_usage()”,对于 Javascript,我使用“process.memoryUsage()”。我在脚本的开头运行它们,然后在结尾,然后用 start 减去 end,最后将字节数转换为 mb。

PHP 使用 0.00065 mb 的内存,而 Javascript 使用 0.25 mb,但是 PHP 需要 4 秒,而 Javascript 需要 0.71 秒。我已经在 2 台不同的机器上运行了结果。

有谁知道为什么 Javascript 的内存使用率会比 PHP 高得多(尽管 Javascript 的执行速度要快得多)?

我能想到的唯一解释是 V8 使用隐藏类的特性提高了速度但增加了内存消耗。

【问题讨论】:

  • 请注意:脚本不一样。 php 函数中的 vars 是私有的,在 js 中是全局变量。
  • 您的测试示例并不像它们可能的那样相似。在 JavaScript 中,您应该将 Iterate 方法作为 First 原型对象的一部分应用……这样您就不会在每次执行时重新创建该方法(这更接近 php 的行为方式)。
  • @pebbl 谢谢。类似于 First.prototype.Iterate = function()
  • 是的。而不是你所做的:- function First(){}; First.prototype.Iterate = function() { ... } 显然 ... 应该替换为 Iterate 函数体代码(我没有空间适合这里)。通过这样做,这意味着 Iterate 函数只创建一次......如果这没有降低您的 js mem 使用率,我会感到惊讶,但这确实取决于现代浏览器现在所做的优化(它们变得越来越复杂)野兽)。
  • 这可能不是大小/速度的权衡,而是一个偶然的、毫无意义的事情。没有人特别关心通用 PC 上这个级别的内存使用情况,当然也没有人试图优化如此小的数字以使它们变得微不足道。如果我不得不猜测,我猜想由于这段代码的运行,javascript 正在初始化一些正在运行不相关代码(例如垃圾收集)的东西,并且您会看到它的内存使用情况。

标签: javascript node.js memory php


【解决方案1】:

因为它们是非常不同的执行环境。

在 PHP 的情况下,源代码被转换为一系列操作码 - 有点像 p-code,而 v8 使用 JIT 编译器。后者会更倾向于使用内存,但我怀疑 2 之间内存使用的最大区别是由于垃圾收集的不同策略:

$test_array = split(" ", $test_string);

和

test_array = test_string.split(" ");

在堆栈上创建一个对象,该对象在每次迭代结束时被丢弃。

两者都没有提供太多控制运行时内存使用的访问权限。

【讨论】:

  • 谢谢,我将修改本地变量,使其在每次迭代中都不同,看看随着堆栈现在正确增加会产生什么。
猜你喜欢
  • 2015-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多