1

I've made a simple object creation benchmark. I know "there are lies, damn lies and benchmarks", however the difference seems huge. Can anyone tell me if I'm doing something wrong. Or if not, how is it possible? I'm new to JS so please don't beat me.

http://jsperf.com/factoryvsconstvsobjectcreate/3

/Edit thanks Andrew Fedoniouk for a little bugfix

Krzysztof Wende
  • 3,208
  • 25
  • 38
  • I believe your test case is not correct - not clear what you measure there. Here is test measuring speed of object creation: http://jsperf.com/factoryvsconstvsobjectcreate/4 – c-smile Jan 07 '14 at 17:42
  • @c-smile Your test has a bug. It assigns returned value to obj each time in factory. And after all. I want to measure whole pattern, not just object creation of it. – Krzysztof Wende Jan 07 '14 at 17:46
  • 1
    Yep, check this http://jsperf.com/factoryvsconstvsobjectcreate/5 then. Difference between literal creation and creation by constructor is insignificant I would say. As whole pattern testing, I don't think it is practical. Usually class/factory declarations happen only once - at start-up. – c-smile Jan 07 '14 at 18:31
  • You're right. Does anyone know how would it stand for memory? – Krzysztof Wende Jan 07 '14 at 19:17
  • The funny thing is even in your test there is a difference. But maybe that's the price of working instanceof and rest of it. – Krzysztof Wende Jan 07 '14 at 22:18

1 Answers1

0

The huge difference between the Factory and Constructor tests is due to a series of extra steps performed in the latter.

When a function is invoked as a constructor, its [[Construct]] internal method is invoked, and that's likely the cause of the performance difference. Look at all the steps involved in [[Construct]]:

1. Let obj be a newly created native ECMAScript object.

2. Set all the internal methods of obj as specified in 8.12.

3. Set the [[Class]] internal property of obj to "Object".

4. Set the [[Extensible]] internal property of obj to true.

5. Let proto be the value of calling the [[Get]] internal property of F with argument "prototype".

6. If Type(proto) is Object, set the [[Prototype]] internal property of obj to proto.

7. If Type(proto) is not Object, set the [[Prototype]] internal property of obj to the standard built-in Object prototype object as described in 15.2.4.

8. Let result be the result of calling the [[Call]] internal property of F, providing obj as the this value and providing the argument list passed into [[Construct]] as args.

9. If Type(result) is Object then return result.

10. Return obj.

bfavaretto
  • 71,580
  • 16
  • 111
  • 150
  • For completeness there is also should be a list of steps involved in factory case. You'd be surprised but these steps are pretty much the same in both cases. – c-smile Jan 07 '14 at 17:35
  • @c-smile My point is that the factory method only calls [[call]], while the constructor method calls [[construct]], which in turn calls [[call]] in step 8. So there's the overhead. – bfavaretto Jan 07 '14 at 17:50
  • I would be interested to see just the results of `new Constructor()`, `factory()` and `Object.create(...)` since you have a few lines of code in each test that just do setup. What you are really interested in is the object generation part of things. – Greg Burghardt Jan 07 '14 at 17:51