16

I've seen little utility routines in various languages that, for a desired array capacity, will compute an "ideal size" for the array. These routines are typically used when it's okay for the allocated array to be larger than the capacity. They usually work by computing an array length such that the allocated block size (in bytes) plus a memory allocation overhead is the smallest exact power of 2 needed for a given capacity. Depending on the memory management scheme, this can significantly reduce memory fragmentation as memory blocks are allocated and then freed.

JavaScript allows one to construct arrays with predefined length. So does the concept of "ideal size" apply? I can think of four arguments against it (in no particular order):

  • JS memory management systems work in a way that would not benefit from such a strategy
  • JS engines already implement such a sizing strategy internally
  • JS engines don't really keep arrays as contiguous memory blocks, so the whole idea is moot (except for typed arrays)
  • The idea applies, but memory management is so engine-dependent that no single "ideal size" strategy would be workable

On the other hand, perhaps all of those arguments are wrong and a little utility routine would actually be effective (as in: make a measurable difference in script performance).

So: Can one write an effective "ideal size" routine for JavaScript arrays?

6
  • 1
    I'm for "..a little [benchmark] utility routine would actually be effective [in determining implementation performance]" Commented Jan 24, 2014 at 21:35
  • 1
    (not my comment) This question is very engine dependent Commented Jan 24, 2014 at 21:35
  • 1
    sparse arrays are more like assocArrays in other languages, so i doubt there would be consistent benefit. also, having undefined in an array also implies a mixed type array which causes V8 to box the structure and slows down IO considerably. Commented Jan 24, 2014 at 21:36
  • (my comment) How often do you create an array with a fixed size? Personally, I've never done it, so there is no "ideal size" for me I guess. Commented Jan 24, 2014 at 21:38
  • @dandavis if you do Arrray(2014), chances are the browser will expect you to fill it with 2014 values right afterwards, and prepare for that case. Commented Jan 24, 2014 at 21:38

3 Answers 3

8

Arrays in javascript are at their core objects. They merely act like arrays through an api. Initializing an array with an argument merely sets the length property with that value.

If the only argument passed to the Array constructor is an integer between 0 and 232-1 (inclusive), this returns a new JavaScript array with length set to that number. -Array MDN

Also, there is no array "Type". An array is an Object type. It is thus an Array Object ecma 5.1.

As a result, there will be no difference in memory usage between using

var one = new Array();
var two = new Array(1000);

aside from the length property. When tested in a loop using chrome's memory timeline, this checks out as well. Creating 1000 of each of those both result in roughly 2.2MB of allocation on my machine.

one

two enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

Sounds pretty much like my third bullet. :)
I just noticed this in your answer: "Also, there is no array "Type". An array is an Object type." I realize that JavaScript is not a typed language, but I was referring specifically to typed arrays like UInt8Array, Float64Array, etc. These provide JavaScript a mechanism to access raw binary data in memory buffers (i.e., ArrayBuffer objects).
1

You'll have to measure performance because there are too many moving parts. The VM and the engine and browser. Then, the virtual memory (the platform windows/linux, the physical available memory and mass storage devices HD/SSD). And, obviously, the current load (presence of other web pages or if server-side, other applications).

I see little use in such an effort. Any ideal size for performance may just not be ideal anymore when another tab loads in the browser or the page is loaded on another machine.

Best thing I see here to improve is development time, write less and be quicker on deploying your website.

Comments

0

I know this question and the answer was about memory usage. BUT although there might be no difference in the allocated memory size between calling the two constructors (with and without the size parameter), there is a difference in performance when filling the array. Chrome engine obviously performs some pre-allocation, as suggested by this code run in the Chrome profiler:

<html>

<body>
<script>
    function preAlloc() {
        var a = new Array(100000);
        
        for(var i = 0; i < a.length; i++) {
            a[i] = i;
        }
    }

    function noAlloc() {
        var a = [];
        var length = 100000;
        for(var i = 0; i < length; i++) {
            a[i] = i;
        }
    }

    function repeat(func, count) {
        var i = 0;
        while (i++ < count) {
            func();
        }
    }
</script>
</body>
Array performance test
<script>
    // 2413 ms scripting
    repeat(noAlloc, 10000);
    repeat(preAlloc, 10000);
    
    
</script>
</html>

The profiler shows that the function with no size parameter took 28 s to allocate and fill 100,000 items array for 1000 times and the function with the size parameter in the array constructor took under 7 seconds.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.