简体   繁体   English

crockford的JavaScript构造函数模式真的应该更快吗?

[英]Is crockford's JavaScript constructor pattern really supposed to be faster?

I recently tried to optimize some code for an often created value object. 我最近尝试为经常创建的值对象优化一些代码。 (A three dimensional vector, fwiw) (三维向量,fwiw)

One thing I tried was to convert the constructor function from an anonymous method factory pattern to a normal JavaScript constructor. 我尝试过的一件事是将构造函数从匿名方法工厂模式转换为普通的JavaScript构造函数。

This led to a severe performance penalty which surprised me, since the use of 'new' and normal constructors was much recommended in my last question on the subject of JavaScript constructor/factory patterns. 这导致严重的性能损失让我感到惊讶,因为在我关于JavaScript构造函数/工厂模式主题的上一个问题中 ,建议使用'new'和普通构造函数。

It could well be that my test is too simplistic, or just plain wrong, or a result of recent performance optimizations made in chrome's JavaScript engine, or all of the above. 很可能是我的测试过于简单,或者只是完全错误,或者是最近在chrome的JavaScript引擎或上述所有内容中进行性能优化的结果。 In any case, I'd really like to know why my 'optimizations' led to performance drop - and - most important: Is there any obvious problem with my jsperf testrun? 无论如何,我真的很想知道为什么我的'优化'导致性能下降 - 而且 - 最重要的是:我的jsperf testrun有没有明显的问题?

The major differences between your tests are: 您的测试之间的主要区别是:

  • {} is way faster than new Object , which suggests that new is simply slower than using {} . {}new Object ,这表明new比使用{}慢。 (The same is true of [] and new Array .) []new Array也是如此。)

  • Your tests produce different results: the result of your make factory function isn't a Make object. 您的测试会产生不同的结果: make工厂函数的结果不是Make对象。 The constructed Make has a prototype, shared by all Make objects. 构造的Make有一个原型,由所有Make对象共享。 Your result of your factory function is just a bare Object , and has a single prototype in its prototype chain ( Object.prototype ), whereas the Make constructed object has two ( Make.prototype , followed by Object.prototype ). 您的工厂函数的结果只是一个裸Object ,并且在其原型链( Object.prototype )中有一个原型,而Make构造的对象有两个( Make.prototype ,后跟Object.prototype )。

    I made a fork of your test , with a factory function that actually returns a Make object (instead a simple Object ), using the non-standard __proto__ property, and it is much slower than a using a constructor. 我使用非标准的__proto__属性实现了一个实际返回Make对象(而不是简单的Object )的工厂函数的测试分支 ,它比使用构造函数慢得多。 IE does not support __proto__ , but the results from Firefox and Chrome look pretty definitive. IE不支持__proto__ ,但Firefox和Chrome的结果看起来非常明确。

One of the things that a constructor function optimizes for is shared properties, usually methods. 构造函数优化的一个方面是共享属性,通常是方法。 If a number of objects use the same functions as methods, or share other named properties, then one assignment to the prototype will share a single instance of the property among all objects created from the constructor, reducing memory overhead, and will not need to repeat the assignment of each such property for every object created, reducing construction time overhead. 如果许多对象使用与方法相同的函数,或者共享其他命名属性,那么对原型的一个赋值将在从构造函数创建的所有对象中共享该属性的单个实例,从而减少内存开销,并且不需要重复为每个创建的对象分配每个这样的属性,减少了构建时间开销。

Since your sample does not include any such properties, you're not going to see such benefits. 由于您的样本不包含任何此类属性,因此您不会看到此类好处。 But if your production code does not include shared properties for your constructed object, there might well be no reason to switch to a constructor. 但是,如果您的生产代码不包含构造对象的共享属性,则可能没有理由切换到构造函数。

So, if, for example you had code like this : 所以,如果,例如你有代码这样的

function make(p) {
    return {
        parm: p,
        addTwo: function() {return this.parm + 2;},
        double: function() {return this.parm * 2;},
        square: function() {return this.parm * this.parm;}
    };
};

it will probably run more slowly than this: 它可能比这更慢:

function Make(p) {
    this.parm = p;
}
Make.prototype.addTwo = function() {return this.parm + 2;};
Make.prototype.double = function() {return this.parm * 2;}
Make.prototype.square = function() {return this.parm * this.parm;}

It will also take a lot more memory if you create many instances. 如果您创建许多实例,它还会占用更多内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM