How to write efficient code for Node/MongoDB mixed use?

66 views
Skip to first unread message

Sebastian Ferreyra Pons

unread,
Jul 19, 2012, 7:16:17 PM7/19/12
to v8-u...@googlegroups.com
I have two questions.

#1
I'm developing a Node.js/Mongodb web app.

This means that objects used in the code will be created by at least two different code paths:
  1. Constructor functions
  2. Deserialization code in the mongo driver.
It is my understanding that hidden classes are not shared between different constructors, even if I construct structurally identical objects with the same properties and in the same order. This seems to imply that deserialized objects coming from mongodb will not share the same hidden class as structurally identical objects created by the constructors, hence functions that use these objects will not be well optimized into native code. Am I right?

#2
Is there any hidden class inheritance built into v8? That is, if I create object o={a:1, b:2} and later add o.z=3, will native code optimized for the hidden class before the property-add still work unmodified afterwards?

jMerliN

unread,
Jul 20, 2012, 1:21:39 AM7/20/12
to v8-users
Hi Sebastian,

> It is my understanding that hidden classes are not shared between different
> constructors, even if I construct structurally identical objects with the
> same properties and in the same order. This seems to imply that
> deserialized objects coming from mongodb will not share the same hidden
> class as structurally identical objects created by the constructors, hence
> functions that use these objects will not be well optimized into native
> code. Am I right?

Yes. In a constructor function, the hidden class begins with an
element that also includes a prototype. In two different constructor
functions these initial elements will be different, making their
hidden classes different.

If you have hot code that is being impacted because you pass it both
objects you construct and ones from the MongoDB driver you're using,
one thing you can do is make your constructor take the MongoDB object
representation as an input. Then you would be able to make your hot
code monomorphic. If you don't have any hot code being impacted, it's
probably not something you should worry about unless your Mongo driver
is putting objects it constructs into dictionary mode for some reason.

An example: http://jsfiddle.net/xznxP/

"hot" only deoptimizes when given the raw object here, which has a
different hidden class.

> Is there any hidden class inheritance built into v8? That is, if I create
> object o={a:1, b:2} and later add o.z=3, will native code optimized for the
> hidden class before the property-add still work unmodified afterwards?

No.

- Justin

On Jul 19, 4:16 pm, Sebastian Ferreyra Pons <ushiferre...@gmail.com>
wrote:
> I have two questions.
>
> #1
> I'm developing a Node.js/Mongodb web app.
>
> This means that objects used in the code will be created by at least two
> different code paths:
>
>    1. Constructor functions
>    2. Deserialization code in the mongo driver.

Sebastian Ferreyra Pons

unread,
Jul 23, 2012, 10:48:22 AM7/23/12
to v8-u...@googlegroups.com
> Yes.  In a constructor function, the hidden class begins with an 
> element that also includes a prototype.  In two different constructor 
> functions these initial elements will be different, making their 
> hidden classes different.  

Does this mean that if I make sure that both the mongo driver and my code uses the literal empty object {} for creating new objects they will share the same root class?

Vyacheslav Egorov

unread,
Jul 23, 2012, 10:53:20 AM7/23/12
to v8-u...@googlegroups.com
Yes.
--
Vyacheslav Egorov
> --
> v8-users mailing list
> v8-u...@googlegroups.com
> http://groups.google.com/group/v8-users

Sebastian Ferreyra Pons

unread,
Jul 23, 2012, 3:15:04 PM7/23/12
to v8-u...@googlegroups.com
Ok, this means I have a shot at having my code compiled monomorphically by creating my objects without prototype, which I don't need anyway because such information is useless to me as it's not stored in JSON/BSON. 

How about these two objects. would they share the same hidden map?

var o1 = {};
o1.x = 1;

var o2 = {x:1};

Thanks!

Sebastian Ferreyra Pons

unread,
Jul 24, 2012, 1:37:40 AM7/24/12
to v8-u...@googlegroups.com
I had some time tonight and I did some testing of my own. 

Apparently, objects whose properties are set inside the literal block do not share the same hidden map/class with those whose properties are set later using dot or bracket notation. These latter two however can be used interchangeably with identical results.

I imagine it was done this way in order to save memory, but it is a disadvantage when the code has to process structurally identical objects that are potentially constructed in different places. And the memory savings are gone in that case as well because there have to be separate hidden classes for each origin.

I didn't look at the v8 source and I'm only speculating but if this is the case then perhaps a command line flag that makes literal objects build a class chain like if one were using dot/bracket notation so that they share hidden classes would be a neat setting to have for this situation.
Reply all
Reply to author
Forward
0 new messages