Reputation: 2257
Basic JavaScript question: Since there is no hard limit for arrays as the case with Java (i.e. IndexOutOfBoundsException), what is the use of the declaration where we specify the length property?
var a = new Array(10);
I know it predefines the length and puts "undefined" into those empty spots. Is that reason enough for having it?
Upvotes: 59
Views: 81103
Reputation: 3620
As all of the answers with actual benchmarks no longer load, I created a new benchmark: https://jsbench.me/hhlk3jgvu4/1
The results on Chrome on macOS as of July 2023 are:
1. fillArrayWithSetLen 19K ops/s
2. fillArrayWithLenConstructor 18K ops/s ( 2.87% slower)
3. fillArrayWithLiteral 17K ops/s (11.71% slower)
4. fillArrayWithPush 15K ops/s (20.36% slower)
A second run with a randomized order yielded the same relative ranking:
1. fillArrayWithSetLen 19K ops/s
2. fillArrayWithLenConstructor 19K ops/s ( 1.98% slower)
3. fillArrayWithLiteral 16K ops/s (15.58% slower)
4. fillArrayWithPush 16K ops/s (19.85% slower)
Code in case the benchmark site disappears:
const testLen = () => {
const rand = Math.random();
return rand < 1 ? 4192 : rand;
}
const fillArrayWithPush = (len) => {
const ar = [];
for (let i = 0; i < len; i++) {
ar.push({x: i, y: i + 1, z: i + 2, str: `str${i}`});
}
return ar;
};
const fillArrayWithLenConstructor = (len) => {
const ar = new Array(len);
for (let i = 0; i < len; i++) {
ar[i] = {x: i, y: i + 1, z: i + 2, str: `str${i}`};
}
return ar;
};
const fillArrayWithLiteral = (len) => {
const ar = [];
for (let i = 0; i < len; i++) {
ar[i] = {x: i, y: i + 1, z: i + 2, str: `str${i}`};
}
return ar;
};
const fillArrayWithSetLen = (len) => {
const ar = [];
ar.length = len;
for (let i = 0; i < len; i++) {
ar[i] = {x: i, y: i + 1, z: i + 2, str: `str${i}`};
}
return ar;
};
Upvotes: 0
Reputation: 41
Suppose you want an array of a certain length initialized to a certain value. This will not work:
scores = [].fill(0.0, 0, studentCount);
It'll just give you an empty array, because fill() will never extend the array beyond its original length.
This will work:
scores = new Array(studentCount).fill(0.0, 0, studentCount);
It'll give you an array of studentCount values initialized to zero.
Upvotes: 4
Reputation: 842
Its not hard to maintain array size. Take a look on following example :
function updateArray(){
var a = [1,2,3,4,5,6,7,8,9,10]; //original array object
var b = [11, 12, 13]; //New array object to be pushed
a.splice(a.length-b.length, a.length);
a.unshift.apply(a, b);
return a;
}
a.unshift.apply(arg1, arg2)
push the new element on top and a.push.apply(arg1, arg2)
at bottom.
Upvotes: 0
Reputation: 320
I've created this JSPerf which demonstrates the problem, including it's various versions. Arguments I find are such:
I think these tests should put those arguments to rest, but it should be noted that different browsers treat this problem very differently. Firefox seems to optimize and figure out how large the array will be, while Chrome allocates memory as one would expect. And, as usual, Internet Explorer just stinks at the task.
Upvotes: 2
Reputation: 16214
Well, personally i want a queue. I want the queue to be length of 10.
The easiest way to do this is to use the push
array method to put items onto the end of the queue, and the shift()
method to get them off the front of the array.
The problem is, if i want to make a simple "add" method to my queue, and i write it up like so:
function addItemToArray(item, array){
array.shift();
array.push(item);
return array;
}
then Nothing Good happens. What is better (actually, what will work) is to declare my array like this:
var maxSizeIsTen = new Array(10);
and then use it everywhere. Also, note the "nice" way of describing the array - no comments that nobody reads, and anybody using this code will work out in short order the max size of this array.
YAY!
Upvotes: 0
Reputation: 1018
Performance on the V8 JavaScript engine.
By doing:
var arr = []; arr.length = 1000;
V8 will preallocate the required memory for the array and maintain/set the array's Hidden Class
to compact SMI (Small Int, 31 bits unsigned) array. However, this is not true when the desired length is too big, which results in the HC being set to sparse array (i.e., map).
Try the following link on Chrome: http://jsperf.com/0-fill-n-size-array
I've included an extra test case without the array length definition so you can tell the actual performance difference.
Related info: http://www.youtube.com/watch?v=UJPdhx5zTaw
Upvotes: 34
Reputation: 11177
There are many perceived benefits of declaring an array size, but I think the majority of the perceived benefits are just FUD being passed around.
Better performance!/It's faster!
As far as I can tell the difference between pre-allocating and dynamic allocation is negligible.
More interestingly, the spec does not state that the array should be set to a pre-allocated length!
From Section 15.4.2.2 ECMA-262:
If the argument len is a Number and ToUint32(len) is equal to len, then the length property of the newly constructed object is set to ToUint32(len). If the argument len is a Number and ToUint32(len) is not equal to len, a RangeError exception is thrown.
An unscientific for-fun test case is here: http://jsbin.com/izini
It makes for more understandable code!
Personally, I disagree.
Consider the javascript you have written in the past, and consider code you may have to write in the future. I can't think of a single time where I've needed to specify a static limit on one of my arrays. I'd also argue that the potential problems of limiting arrays in javascript highly outweigh the benefits caused by letting people know what you were thinking with no actual checks behind it. Lets weigh the pros and cons...
Pros:
Cons:
You may as well have written:
//I assume this array will always be length 10
var arr = new Array();
In the above case the comment might even be preferable. The explicit declaration of intent can avoid any confusion not used to using the constructor as a declaration of intent.
Fine then.. why do you think it's even there then?
Convenience. When they were writing the spec I think they realized two things.
So they put it in there. The spec only defines the use of the parameter, not how it should be implemented.
Upvotes: 41
Reputation: 15365
Clarity.
When writing code, your goal is not so much for the computer to understand you, but for the next programmer that reads your code to understand you.
var xs = new Array(10);
The above code shows your intention: to have a 10 element array.
var xs = [];
The above gives nothing away; no extra information.
Cheers.
Upvotes: 14
Reputation: 12509
I am not sure, but I would bet it allocates memory differently at a low level. If you know you're creating 10,000 items, just reserve that much space rather than dynamically having it resize it in the background all the time.
Upvotes: 8