7

I tried Dart SDK after the 1.0 release, and wrote a simple hello-world program in Dart. Then, with the SDK tool, I generated the JavaScript file: helloworld.dart.js I went through the output js code, I saw there is a function named convertToFastObject. The definition is:

function convertToFastObject(properties) {
    function MyClass() {};
    MyClass.prototype = properties;
    new MyClass();
    return properties;
}

The usage code is like:

A = convertToFastObject(A);
B = convertToFastObject(B);

I know this code is for various kinds of Browsers, not for Chromium/Chrome only. I cannot understand, why the function can make the Object faster?

mingjun
  • 73
  • 4
  • Note that this code might be an improvement for Chrome/Chromium only. Google optimizes code for their own V8 engine. Other engines might see an improvement, or they might not; that's not Google's main concern. – apsillers Nov 20 '13 at 14:34
  • 1
    It appears that Dart people think that objects used as prototype are faster than objects who are not used as prototype. Why that is, i cannot say, but i assume it has something to do with JS engine internals. – Tibos Nov 20 '13 at 14:57

2 Answers2

10

This is a speed optimization for Google's V8 engine.

To be sure, this code snippet looks pretty weird: it assigns properties as the prototype of a constructor MyClass, then uses the constructor to build an instance with new MyClass(), and then returns properties. This is strange because 1) properties is never altered, and 2) the function never uses MyClass or the instance ever again.

Whenever you see strange behaviors like this, you can be fairly sure it's a speed optimization. In this case, the speed is gained by using V8's "hidden class" optimization. From a closely-related section of the Dart source:

// Use the newly created object as prototype. In Chrome,
// this creates a hidden class for the object and makes
// sure it is fast to access.

In the V8 engine, a constructed object is given a "hidden" C++ class to represent its set of properties. By constructing an object whose prototype is the properties object, the property values of properties become part of the new instance's C++ hidden class, which improves property-access speed.

I believe all objects in V8 have hidden classes by default, so the need for this technique isn't immediately obvious. However, it is possible for an object to lose its hidden class (and enter "slow mode" or "dictionary mode") by demonstrating that it doesn't benefit from the optimization. When an object deletes one of its properties or adds too many properties that are unrelated to the properties of any other objects, V8 assumes that a shared hidden class isn't valuable, because the object has no other similar object to share its hidden class with. This convertToFastObject function can re-instate a "slow mode" object's right to a hidden class by using it as the prototype of a newly constructed instance.

Related hidden class question, arising from a different Dart optimization: What is this generated code supposed (intended) to do?

Community
  • 1
  • 1
apsillers
  • 112,806
  • 17
  • 235
  • 239
  • In fact at first it seems to me referring to prototypal inheritance as explained here by Mr. Crockford http://javascript.crockford.com/prototypal.html But `return properties;` invalidates all. Good answer. – ilpaijin Nov 20 '13 at 15:34
  • @ilpaijin There is no actual inheritance here. The class and the instance are discarded as soon as the function has executed. In fact, `A = convertToFastObject(A);` doesn't have any effect from the script's perspective. All it does is inform the JS engine that A is special (is used as a prototype for a class). – Tibos Nov 20 '13 at 15:50
  • Yes, in fact. As I wrote. Good answer. – ilpaijin Nov 20 '13 at 15:52
  • By my test, there is an improvement of 10 times in the code that runs after calling this function in chrome :) – Salvatore Previti Dec 24 '14 at 18:27
-1

Where data is stored in a script contributes directly to the amount of time it takes to execute. In general, there are four places from which data can be accessed in a script:
-Literal value
-Variable
-Array item
-Object property

Reading data always incurs a performance cost, and that cost depends on which of these four locations the data is stored in. if you create a property using the "Object.Prototype.", the scope here is "Object.Prototype" which is smaller than the object's scope "Object." that hold in addition the local vars and stuff non enumerable. That is why creating proprieties using Prototype have a faster access ! Read these 2 articles to get better understanding: 1- http://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html 2-http://www.packtpub.com/article/using-prototype-property-in-javascript

e-nouri
  • 2,576
  • 1
  • 21
  • 36
  • 2
    This does not appear to answer the question, since the `properties` object is never actually used as a prototype. The only instance of `MyClass` is thrown out immediately; it is never used nor even stored inside a variable. – apsillers Nov 20 '13 at 15:42
  • you instantiate MyClass so you can have access to prototype properties ! you need the properties not The instance of MyClass ! – e-nouri Nov 20 '13 at 16:07