【问题标题】:Javascript: Why is my optimized loop slower than the more naive oneJavascript:为什么我的优化循环比更天真的循环慢
【发布时间】:2017-09-03 22:58:25
【问题描述】:

如果您喜欢 jsperf 的格式,请链接到它:https://jsperf.com/test-array-vs-loop-vs-loop-optimized

我正在尝试使用旧的 jsperf 循环与过滤器,并尝试通过在大小正确时预先分配数组并避免重新计算项目长度来优化循环。问题是它没有在我的 Chrome 60 上运行得更快。

代码如下:

var items = [];
var names = ['george', 'nick', 'jack', 'herodotus', 'joanne'];
for (var i = 0; i < 2000; i++) {
    var obj = {
        name: names[i % 5] + '-' + i,
        age: i % 10 + 15
    };
    items.push(obj);
}

function filter_callback(item) {
    return (item.age == '18');
}

function test_filter() {
    var aged_18_filter = items.filter(filter_callback);
}

function test_loop() {
    var aged_18_loop = [];
    for (var i = 0; i < items.length; i++) {
        if (items[i].age == '18') aged_18_loop.push(items[i]);
    }
}

function test_loop_optimized() {
    var length=items.length
    var aged_18_loop = new Array(length);
    for (var i = 0; i < length; i++) {
        if (items[i].age == '18') aged_18_loop[i]=items[i];
    }
}

编辑:正常循环的结果约为 39,281 ops/sec,“优化”循环的结果约为 37,389 ops/sec。在 i7 3610QM 上。

【问题讨论】:

  • 我不明白你的优化是什么。
  • 提示:new Array(length)wrong 大小,如果您尝试过滤,并且通过分配给 aged_18_loop[i] 而不是数组的末尾,您甚至可以创建一个带孔的稀疏数组。我不认为那是你想要的。
  • 你得到了什么结果,你能把它们贴出来吗?我手头没有 Chrome 60。
  • 谢谢,我现在完全明白了。正常循环的结果约为 39,281 ops/sec,“优化”循环的结果约为 37,389 ops/sec。在 i7 3610QM 上。 @swailem95 我的最后一个函数预先分配了循环,并在循环条件中使用了“var length”而不是“items.length”。

标签: javascript arrays performance loops


【解决方案1】:

如果大小正确,我尝试通过预分配数组来优化循环

但是你失败了。过滤结果通常与输入的大小不同。通过不在数组末尾附加(使用push)并始终分配给索引i,您甚至可以创建一个稀疏数组。 (鉴于您的样本非常小,至少影响不大)。

正确的方法可能是

function test_loop_optimized() {
    var length = items.length;
    // let's guess that the result will have about a fifth of the size
    var result = new Array(Math.round(length / 5));
    var i = 0;
    var j = 0;
    while (i < length) {
        var item = items[i++];
        if (item.age == '18')
            result[j++] = item;
    }
    result.length = j; // just in case we guessed too high
    return result;
}

...并避免重新计算项目长度

这是一个微不足道的优化,JS 引擎确实可以自行应用。访问.length 实际上并不慢。除非发生了什么奇怪的事情,否则你不会从拼写中受益。

【讨论】:

    猜你喜欢
    • 2015-10-07
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    • 2018-10-11
    • 2017-11-09
    • 2019-09-29
    • 2017-10-04
    相关资源
    最近更新 更多