gpt4 book ai didi

javascript - 为什么在 V8 上调用对象字面量的方法会更慢?

转载 作者:可可西里 更新时间:2023-11-01 02:30:26 26 4
gpt4 key购买 nike

我对这个 simple jsperf test 的结果感到惊讶:

Benchmark.prototype.setup = function() {
var O = function() {
this.f = function(){};
}
var o = new O();
var o2 = {
f : function(){}
};
};

// Test case #1
o.f(); // ~721M ops/s

// Test case #2
o2.f(); // ~135M ops/s

我希望两者执行相同(事实上,Firefox 中的性能相似)。 V8 一定在案例 #1 上优化了一些东西,但是什么?

最佳答案

关于 V8 和 jsPerf 的初步基础:

  • V8 使用一种称为隐藏类 的技术。每个隐藏类都描述了特定的对象形状,例如对象在偏移 16 处具有属性 x对象具有方法 f 并且这些隐藏类与 transitions 连接在一起,因为对象发生变异形成 transition trees(严格来说是 dag)。并非所有隐藏类都位于同一个转换树中;相反,每个构造函数都会生成一个新的转换树。看看these slides掌握隐藏类背后的基本思想。

  • 当 jsPerf 执行以下操作来运行您的测试时:给定 setupbody多次生成并运行一个看起来像大概是这样的:

    function measure() {
    /* setup */
    var start = Date.now();
    for (var i = 0; i < N; i++) {
    /* body */
    }
    var end = Date.now();

    /* N / (start - end) determines ops / ms reported */
    }

    每次运行都称为一个样本

现在让我们看一下基准测试中的转换树。

  1. o 的隐藏类属于转换树,其根位于构造函数O。请注意,每个构造函数都被调用一次。这允许 V8 在内存中构建以下转换树:

    O{} -f-> O{ f: <closure> }

    o 的隐藏类实质上告诉 V8 o 有一个由给定闭包实现的名为 f 的方法 .这允许 V8 的优化编译器在上面的基准测试中内联 f,这实际上使基准测试循环为空。

  2. o2的隐藏类属于Object的转换树。首先注意 setup 被多次调用,所以如果 V8 尝试应用相同的优化将 f 提升到一个方法,它将到达一个不可能的转换树:

    Object{} -f-> Object{ f: <closure> }
    -f-> Object{ f: <other closure> }

    事实上,V8 甚至没有尝试。 V8 实现者预见到了这种情况,V8 只是让 f 成为一个普通属性:

    Object{} -f-> Object{ f: <property at offset 8> }

    因此要调用 o2.f() 需要先加载它,这也会损害内联。

在这里你应该意识到一件重要的事情:如果你两次调用 O 构造函数那么 V8 将到达 V8 避免命中 Object 的同一个不可能的转换树:

    O{} -f-> O{ f: <closure> }
-f-> O{ f: <other closure> }

你不能有那样的结构。在这种情况下,V8 即时将 f 转换为一个字段,而不是使其成为一个方法并重写转换树:

    O{} -f-> O{ f: <property at offset 8> }

http://jsperf.com/function-call-on-js-objects/3 中查看此效果我在创建 o 之前添加了一个 new O()。您会注意到对象字面量和使用 new 构造的对象的性能是相同的。

这里的另一个细节是,如果文字是在全局范围中声明的,V8 也会尝试将 f 转换为文字的方法。参见 http://jsperf.com/function-call-on-js-objects/5Issue 2246反对V8。这里的推理很简单:全局范围内的文字只被评估一次,因此这种提升很可能会成功,并且如果多次评估文字会出现方法之间的冲突。

您可以在 my blog post 中阅读有关类似问题的更多信息.

关于javascript - 为什么在 V8 上调用对象字面量的方法会更慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22057579/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com