Memory layout in Javascript - data-oriented vs object-oriented design [closed]
Asked Answered
E

2

22

Coming from a background of C/C++, memory layout of objects with regards to reducing cache misses is something that is crucial especially when working on consoles. Data-oriented design is often favored over object-oriented design, in order to help keep related objects close to each other in memory (especially in performance critical areas).

Recently, I've been doing some Javascript development, and I'm wondering what the general consensus is within the Javascript community.

With my limited experience in Javascript, I've often been surprised to see completely unexpected results when profiling. The internal memory layout and implementation of Javascript objects/structures varies so greatly from browser to browser, that I wonder if it is worth the effort to attempt to optimize.

I created a simple test case (http://jsperf.com/object-vs-data) on jsPerf to compare the performance of the two methods, and while it shows performance gains on Chrome, there is no noticeable speedup on Safari.

In Javascript, should I even concern myself with the memory layout of objects? Or is it more of a 'implement it one way and then optimize if needed' type thing?

This second option seems kind of wasteful (in terms of development time), especially if there is some good guideline to follow.

Thanks~

Supplemental Information: This is basically how I would implement the two approaches in Javascript. The jsPerf test case above is implemented like this.

var objectOriented = [
    { foo: 1, bar: 2 },
    { foo: 3, bar: 4 }
];

var dataOriented = {
    foos: [1, 3],
    bars: [2, 4]
};

// Object-oriented access:
var a = objectOriented[0].bar;

// Data-oriented access:
var b = dataOriented.bars[0];
Extrorse answered 30/7, 2014 at 15:46 Comment(9)
perfect question... +1 but I am afraid if this is primarily opinion based.Stopper
I think if the foos and the bars are someway connected more than the bars with other bars and the foos with other foos, I would recommend the first method. Also the time saving is pretty small. This particular function has to run at least 600,000,000 times in order to make up for your 5 minutes thinking about it.Hookup
JS is a very high level language so I'm pretty sure you don't have to worry about the memory layout of your data structures. How you structure your objects is also pretty much up to you, it might be a good idea to think of a more concrete use case for your data to find a good representation.Formularize
I wasn't aware hitting the [Run Test] button did anything so I apologize for the firefox test if that messed anything up :(Horthy
@Horthy the whole idea of jsperf is to gather results from different browsers so I'm pretty sure there is no harm down.Formularize
@WillemD'haeseleer ok good. Plus, i blew everyone's results out of the water haha.Horthy
Purely my opinion: JS engines seem to be playing "keeping up with the Joneses" with each other, with Chrome mostly running the show (although Firefox does out perform them in certain cases). So it's my belief that, if you really need to optimize, optimize such that it performs better for Chrome or Firefox because they're leading the charge. But this isn't concrete fact, only future speculation.Woolly
Unless you are working with typed arrays (and access them through a DataView or so), you hardly can manage memory layout. Also, everything is an object, so you can't really create OOP-less pure-data objects.Amazing
You know what they say about premature optimization... (also, closing because this is primarily opinion based)Slotter
C
17

You're working from a fundamental assumption that objects in Javascript work like they do in C++. They don't.

In C++, the primary purpose of a type is to act as a "lens" over a chunk of memory. The class layout directly defines the contents of the memory that the object describes, in a well defined way. C/C++ arrays specifically require a linear, continuous layout of homogeneous types.

In JavaScript, an object is a collection of name/value pairs. An array is just an object with a special "length" property. Note that there's NO description or definition of memory layout here. There's nothing stopping a Javascript interpreter from implementing arrays as a hash table rather than a linear chunk of memory; in fact, I'm sure they are JS implementations that do just that.

JavaScript implementations are free to lay out memory however they want, and there's no correspondence between anything you do in source and what actually ends up in the machine.

In addition, JavaScript arrays are heterogeneous, not homogeneous. That is, assuming that it was laid out in contiguous memory, your equivalent type in C would be JSObject **, not int ** (or float ** or whatever). A JS array is a collection of references to data stored elsewhere, so even if the references were in your cache line, your data won't be.

So, in summary - this kind of thinking will gain you nothing but pain. JavaScript is a much higher level language than C++, and part of that is giving up the control you're used to. That kind of low-level optimization if possible will be done by the interpreter. Concentrate on writing code with efficient algorithms that naturally express your solution; that's hard enough as it is. :-)

Chairmanship answered 30/7, 2014 at 17:28 Comment(0)
S
5

Ok. Fiddled with some numbers and test cases..

Firstly I created this test case http://jsperf.com/object-vs-array-creation-for-so In this case, creating Object is way more faster then creating an Array

Secondly I created this test case http://jsperf.com/accessing-speed In this, there was hardly any difference between them..

So, what I infer from this profile is that using objects more than arrays will be faster if the project is really huge.. as, from the first case, it's clear that object creation is faster than array creation.

But..

Javascript is a highly developed & performant language and you shouldn't be worried with such micro-optimizations. All you should focus is on the semantics. You should choose the structure which best describes your intention..

Testing in Chrome 36.0.1985.125 on Windows NT 6.3

Stopper answered 30/7, 2014 at 16:6 Comment(3)
Interesting, Firefox has the same results for creating an Object and an Array.Horthy
For new users landing here: they now run neck-and-neck. Just use whichever makes sense in your context, it shouldn't matter for performance.Maihem
@JoshPowlison - none of the tests here really test the problem. For most web devs, it's unlikely that arrays are going to be large enough to justify memory layout optimization. Far better to look at computation and the network. We can just compile C++ to web assembly or asm.js if we need control over memory these days as well.Zecchino

© 2022 - 2024 — McMap. All rights reserved.