All Articles

Elements kind

I was recently looking into Javascript internals. I did come across this weird thing called “Elements Kind”. In Javascript you can create object with all sort of keys (including unicode). which means you can create objects with Emoji’s as keys. There is one specific type of objects with keys as numeric (Array). V8 and most engines handles array indexes in a special way for optimization.

Array in v8 contains elements. V8 keeps track of elements of each array in the memory and it changes its type depending on the modification done to the array.

Lets say you have an array

 let arr1 = [8, 9, 10];

when you run the above code the array contain v8 classifies this array as containing PACKED_SMI_ELEMENTS where SMI refers to small integers. when you add a new integer to the array

 arr1.push(2);

Now the array value is [8, 9, 10, 2] the type is still PACKED_SMI_EMELENTS.

Lets say you add a floating point number to the above array.

 arr1.push(2.2)

Now the array value becomes [8, 9, 10, 2, 2.2] but now the type changes to more generic one PACKED_DOUBLE_ELEMENTS.

Now let’s say you add a string to the above array.

 arr1.push('a')

Now the type of the array becomes even more generic PACKED_ELEMENTS

Now as you add elements of other types the type V8 stores internally for the array becomes more generic and it becomes less optimized than it was before. Once it has been upgraded to more generic type it cannot go back to more specific one.

Holey Arrays

One think you may have noticed in the above types v8 identifies for arrays is the word PACKED it really means that the array was created without any holes in them. Other way to create array with holes in them. Lets say you create an array with the following code

 let holleyArray = Array(3);

Now the array type internally is HOLEY_ELEMENTS. Arrays with holes are less optimized for array methods than PACKED arrays. Similar to PACKED element types there is also HOLEY_SMI_ELEMENTS, HOLEY_DOUBLE_ELEMENTS. Holes can also be created in array by deleting elements in a packed array.

But like all things in life PACKED arrays are not silver bullets. If you were dealing with an array of thousands of elements in length then creating PACKED array can be time consuming and more so when you expand your array using Array.push v8 allocates additional memory as your array expands. But when you create Holey arrays using

 const arr = Array(100);

then your array creation is much faster initially but array methods like map, reduce, filter, forEach… will be less optimized than packed arrays so there is a trade-off here.