admin管理员组文章数量:1323157
I recently tried to optimize some code for an often created value object. (A three dimensional vector, fwiw)
One thing I tried was to convert the constructor function from an anonymous method factory pattern to a normal JavaScript constructor.
This led to a severe performance penalty which surprised me, since the use of 'new' and normal constructors was much remended in my last question on the subject of JavaScript constructor/factory patterns.
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. 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?
I recently tried to optimize some code for an often created value object. (A three dimensional vector, fwiw)
One thing I tried was to convert the constructor function from an anonymous method factory pattern to a normal JavaScript constructor.
This led to a severe performance penalty which surprised me, since the use of 'new' and normal constructors was much remended in my last question on the subject of JavaScript constructor/factory patterns.
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. 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?
Share edited May 23, 2017 at 11:45 CommunityBot 11 silver badge asked Jan 2, 2013 at 16:17 ZazZaz 3,0342 gold badges24 silver badges29 bronze badges 8- crockford is fastest for me by ~50% – Darren Kopp Commented Jan 2, 2013 at 16:26
- 2 @Zaz: 2 things...1) Does crockford claim his method is faster? I thought it was just that it avoided globals and was therefore "safer". 2) Are you sure what you are showing there is what Crockford remends? I was thinking more along the lines of the last example on this page...javascript.crockford./prototypal.html...if I'm wrong (probably) could you link me to where you're getting this from as I'm currently doing a reread of "The Good Parts" – heisenberg Commented Jan 2, 2013 at 16:45
- you're paring 2 things that don't do the same thing, neither of which is Crockford's object constructor. – Evan Davis Commented Jan 2, 2013 at 17:34
- @Mathletics: There would be no reason to pare two identical bits of code. What behavioral or performance differences are there between the two techniques presented, beyond the construction performance difference already noted? – Scott Sauyet Commented Jan 2, 2013 at 18:37
-
1
@ScottSauyet the question suggests he's testing Crockford's constructor; paring setting
prototype
directly vs using thenew
keyword. Two methods of creating an object, but certainly not "identical bits of code." The entire question is about construction performance, but the tests provided aren't representative of the question that I think the OP thinks he's asking. – Evan Davis Commented Jan 2, 2013 at 18:42
2 Answers
Reset to default 4The major differences between your tests are:
{}
is way faster thannew Object
, which suggests thatnew
is simply slower than using{}
. (The same is true of[]
andnew Array
.)Your tests produce different results: the result of your
make
factory function isn't aMake
object. The constructedMake
has a prototype, shared by allMake
objects. Your result of your factory function is just a bareObject
, and has a single prototype in its prototype chain (Object.prototype
), whereas the Make constructed object has two (Make.prototype
, followed byObject.prototype
).I made a fork of your test, with a factory function that actually returns a
Make
object (instead a simpleObject
), using the non-standard__proto__
property, and it is much slower than a using a constructor. IE does not support__proto__
, but the results from Firefox and Chrome look pretty definitive.
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.
本文标签: performanceIs crockford39s JavaScript constructor pattern really supposed to be fasterStack Overflow
版权声明:本文标题:performance - Is crockford's JavaScript constructor pattern really supposed to be faster? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742140335a2422553.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论