【问题标题】:"Interiting" from null object does not seem to affect performance来自空对象的“Interiting”似乎不会影响性能
【发布时间】:2011-10-22 09:40:26
【问题描述】:

我已经tried 更好地理解为什么应该(或不应该)从 Object (var o = Object.create(null);) 继承。如果我的答案是正确的,性能原因似乎是从 null “继承”的主要可行原因。

所以,我想检查一下(使用名为 JSLitmus 的小巧、方便且可爱的分析器):

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Title</title>

    <script src="JSLitmus.js"></script>
    <script>
    JSLitmus.test('Prototypeless test', function() {
        var o1 = Object.create(null);
        o1.foo = "bar";
        for (i = 0; i < 1000000; ++i) {
          o1.foo;
        };
    });

    JSLitmus.test('Prototypeful test', function() {
        var o2 = {};
        o2.foo = "bar";
        for (i = 0; i < 1000000; ++i) {
          o2.foo;
        };
    });

    </script>

</head>
<body>
</body>
</html>

执行时,我得到了相同的(有争议的)结果。这是否意味着从Object 继承时没有性能损失?

【问题讨论】:

    标签: javascript profiling


    【解决方案1】:

    是的,没有性能损失。

    为什么会有?它没有检查[[Prototype]],因为fooo 自己的属性。

    您想从null 继承的原因是构建您自己的原型链。它只是让你控制。

    一般来说,您希望从 Object.prototype 继承,因为它上面的方法很有用,而且几乎所有代码都“假定”每件事都从它继承。

    但是你可以用特殊的逻辑创建你自己的链

    var newObject = Object.make(null,{
      toString: function  () { return "foobar"; },
      valueOf: function () { return 42;  }
    });
    

    对于Object.make的某些值

    然后创建实例

    var o = Object.create(newObject);
    console.log(o + 3);
    console.log("foo" + o);
    

    Live Example.

    如果您真的想要对.valueOf 和其他方法进行细粒度的自定义控制,那么出于调试目的不从Object.prototype 继承确实是有意义的(即不会意外地使用 Object.prototype 方法而不是您自己的方法) .

    除此之外,我认为它没有真正的用例。它可能会稍微快一点,或者占用的内存稍微少一些。

    【讨论】:

    • 刚刚重新考虑了主要代码 sn-p 并在我自己的答案上方列出。我的逻辑是否一致,重点是(偏执地:)“证明”,好吗?
    【解决方案2】:

    我重新考虑了自己的代码并稍微修改了代码以使 foo 字段查找通过“继承”链传播:

    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Title</title>
    
        <script src="JSLitmus.js"></script>
        <script>
        var o1 = Object.create(null);
        o1.foo = "bar";
    
        var o2 = Object.create(o1);
    
        var count;
    
        JSLitmus.test('Prototypeless test', function() {
            while(--count) {
              o1.foo;
            };
        });
    
        JSLitmus.test('Prototypeful test', function() {
            while(--count) {
              o2.foo;
            };
        });
    
        </script>
    
    </head>
    <body>
    </body>
    </html>
    

    通过这种方式,我在访问o1 属性时的结果提高了 10%。

    【讨论】:

    • 当然可以。因为属性查找不是免费的。然而,现代 JIT 编译器可以将成本降低到接近于零,因此它是一个微优化。
    • 没有理由从null“继承”,呵呵。一些冗余的语言特性。故事的结尾,我猜 :)
    • 正确有一点点,但是你可以想象人们抱怨Object.prototype在他们的原型链中总是
    猜你喜欢
    • 2012-03-20
    • 2019-05-02
    • 2013-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 2015-10-31
    • 1970-01-01
    相关资源
    最近更新 更多