8

I have an array declared as

var arr = new Array();

Then i have an array of objects which are returned by Server. And each object in this array has three fields(always). I have to loop through this and add to the arr array conditionally.

Since this arr is not pre-allocated, it hits performance for large number in the main array.

Is there any way i can pre-allocate the arr array after i get the main response array so that i can avoid this performance issue?

Also how do i get the size of the object?

Thanks.

max
  • 96,212
  • 14
  • 104
  • 165
aneeshere
  • 509
  • 5
  • 16
  • 1
    don't worry about it, seriously, this isn't C, the whole point of higher level languages is not having to worry about this stuff. For your looping problem, just call `Array#filter` on your returned array. – Willem D'Haeseleer May 20 '15 at 14:25
  • 1
    @TasosK. https://gamealchemist.wordpress.com/2013/05/01/lets-get-those-javascript-arrays-to-work-fast/ – aneeshere May 20 '15 at 14:52

3 Answers3

12

Suppose you have 10 objects, and you are going to pass three values from each object to an array. You can initialize your array with length 30 (10*3) by passing the integer 30 to the Array constructor as such:

var numObjects = 10;
var myArray = new Array(3*numObjects);

Please refer to my jsperf benchmark for a proof of the performance gained. In short summary, pre-sizing your array is ~25% faster in Firefox 38, ~81% faster in Chrome 42, and ~16% faster in Internet Explorer 11. Numbers will vary by the individual's experience who runs these benchmarks, but the trend will remain consistent. The optimal performance will result from pre-sizing your arrays.
http://jsperf.com/array-growth-dynamic-vs-preset

A more thorough discussion of this topic has occured here on SO at
How to initialize an array's length in javascript?

Community
  • 1
  • 1
ThisClark
  • 14,352
  • 10
  • 69
  • 100
  • 3
    Can you prove with a benchmark that this has any positive effects? – max May 20 '15 at 14:35
  • 1
    @papirtiger Yes, indeed. – ThisClark May 20 '15 at 14:41
  • @ThisClark , So if i have 10 objects, with each having three values(keys), then the array length will be 30? I mean what if the values for the Key in object is a string? – aneeshere May 20 '15 at 15:02
  • @aneeshere What do you want to put in the array exactly? Key and Value are two different things. Consider `var obj = {'a':1};` The key is `a` and the value is `1`. You can put three `obj` in one array, or you can put only the `a` in an array, or you can put only the `1` in an array. What is it you want to put in your array? – ThisClark May 20 '15 at 15:29
  • I want an array of objects, so means that i want to put obj in the array. – aneeshere May 22 '15 at 07:11
  • @aneeshere This is what I typically do: `var array = [];` and for a new object, `var obj = {};` you can set properties on an object like `obj.a = 'a';` or `obj.one = 1;` and finally you can make many objects in this way and push them on the array like `array.push(obj);` More specific to your original question, suppose you have 100 of these objects, you would want to presize your array like `var array = new Array(100);` In the benchmark I provided, I assigned the object values by index like `array[i] = obj;` Refer to the code in my benchmark. – ThisClark May 22 '15 at 15:45
  • @ThisClark, Let me make it clear for myself. So if i know i have to push 100 objects with three property each into an array do i say `var array = new Array(100);` or `var array = new Array(300);` – aneeshere May 26 '15 at 15:28
  • 2
    @aneeshere You would say `var array = new Array(100);` Objects are pushed onto an array by reference, so by allocating an array of size 100, you are making space for 100 references. This means the object is not copied in the array, so there is no need for you to make additional space for each object's properties. – ThisClark May 26 '15 at 17:49
  • but try this number (10000000*3), it won't finish. This is not a very large number. It might try to request 1G memory – windmaomao Dec 15 '20 at 16:09
1

Thank whatever deity you believe in (or not) that Javascript does not have any direct access to memory allocation. That would have been truly horrible considering the quality of much of the JS littering the interwebs.

Javascript will by itself allocate memory to arrays on creation and reclaim the memory when it is garbage collected. Pre-Filling an array will have no positive effect on memory usage or performance.

Edit: I was wrong. See @ThisClark's answer.

MDN has a pretty good article on how memory management and GC work in javascript.

max
  • 96,212
  • 14
  • 104
  • 165
  • I think the point you and many others may overlook here is the fact that it is not Javascript that has 'direct access to memory allocation' as you say, but rather it is the web browser that implements its version of the language which does have access to memory allocation. Also, in the link you provided, there is nothing indicated that separates Javascript as being unique from other languages in how memory management is handled. The point I took away from the article is this `Regardless of the programming language, memory life cycle is pretty much always the same.` – ThisClark May 20 '15 at 14:46
  • Thanks for sharing your your knowledge, I learned something new here. I was wrong about pre-allocation of arrays and debated with myself if I should remove my answer. I think it may be better put that the browser does not **provide** direct access to memory allocation - it's not an omission rather a conscious design choice. I still shudder to think of what all the jQuery ninjas out there would hack out of there was a `malloc` in the browser. – max May 20 '15 at 14:55
1

You can filter your array using filter function like the below example

var result = [
    {
        age: 15
    },
    {
        age: 21
    },
    {
        age: 25
    }
];

function isGreaterThan20(obj) {
  return obj.age > 20;
}

var arr = result.filter(isGreaterThan20);
// arr becomes [{ age: 21}, { age: 25}]

If you need to pre-allocate an array with defined size, use new Array(size)

Mohamed Shaaban
  • 1,129
  • 6
  • 13