Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is creating objects with alphanumeric keys so slow in new node versions?

Tags:

I run this test in different node versions:

function test() {     var i;     var bigArray = {};      var start = new Date().getTime();      for (i=0; i<100000; i+=1) {         bigArray[i] = {};         var j= Math.floor(Math.random() * 10000000);         bigArray[i]["a" + j] = i.toString(32);         if (i % 1000 === 0) console.log(i);     }      var end = new Date().getTime();     var time = end - start;     console.log('Execution time: ' + time); }  test(); 

As you can see, it just creates an object with 100000 fields where each field is just an object with just one field. The key of this inner object is forced to be alphanumeric (if the key is numeric, it performs normal).

When I run this test in different javascript implementations/versions I get this results:

v0.8.28     ->  2716 ms v0.10.40    -> 73570 ms v0.12.7     -> 92427 ms iojs v2.4.0 ->   510 ms chrome      ->  1473 ms 

I have also tried to run this test in an asynchronous loop (each loop step in in a different tick), but the results are similar to the ones showed above.

I can't understand why this test is so expensive in newer node versions. Why is it so slow? Is there any special v8 flag that can improve this test?

like image 744
jbaylina Avatar asked Jul 22 '15 05:07

jbaylina


1 Answers

In order to handle large and sparse arrays, there are two types of array storage internally:

  • Fast Elements: linear storage for compact key sets
  • Dictionary Elements: hash table storage otherwise

It's best not to cause the array storage to flip from one type to another.

Therefore:

  • Use contiguous keys starting at 0 for Arrays
  • Don't pre-allocate large Arrays (e.g. > 64K elements) to their maximum size, instead grow as you go
  • Don't delete elements in arrays, especially numeric arrays
  • Don't load uninitialized or deleted elements

Source and more info: http://www.html5rocks.com/en/tutorials/speed/v8/

PS: this is supposed to improve considerably in the upcoming node.js+io.js version.

like image 114
Felipe Brahm Avatar answered Sep 22 '22 12:09

Felipe Brahm