Обобщенный набор рекомендаций по работе с Exotic Object Array
#array #opti #perf #tips
1] Если Ваш Array имеет фиксированный размер, и при этом его элементы не будут изменяться - смело используйте литеральную форму определения такого обьекта. Например:
3] Если Ваш Array может расти в размерах, относительно его начальной формы - то настоятельно рекомендуется об этом позаботиться заранее. То есть инициализировать Array таким образом, чтобы V8 заранее предоставил достаточное колличество слотов для новых элементов. Потому как мы помним, что подобныя операция стоит очень дорого. Тем дороже чем больше наш Array.
4] Настоятельно рекомендуется не делать дырок в Array
5] Настоятельно рекомендуется в Array держать элементы одного и того же типа:
1. Целые числа в пределе от
3. Все прочие типы данных
6] Не забываем что V8 устроен таким образом, что изменив модель представления Array на худшую, к лучшей уже вернуться нельзя. Только пересоздавать Array.
7] Помним что Array по задумке V8 инженеров, предназначен для обработки данных в условиях, когда для одних и тех же данных многократно повторяются одни и теже операции. Для подобных ситуаций внутри V8 и созданы все оптимизации, которые опираются на описание выше.
8] Памятке по аллокации слотов:
От себя добавлю.
Особенно сильно морочить себе голову для случаев COW не COW нужно только тогда, когда это оказывается внутри кода с сотнями тысяч повторений.
При этом крайне внимательно относится к аллокации новых элементов в массиве. Эта проблема тем больше, чем больше используемый массив.
Бонус:
V8 имеет вторую форму представления Array которая является полным подобием Map и включает ее тогда, когда колличество дырок в массиве превосходит все границы. Например:
Определение данных путем использования JSON.parse является намного более производиетльной формой чем формирование данных при помощи литеральных форм как обьекта так и Array.
Что имеет логичное обоснование и явлется рекомендацией от разработчиков V8: https://v8.dev/blog/cost-of-javascript-2019#json
На данных обьемом около 10 килобайт,выгода от подобной инициализации видна невооруженным взглядом и составляет около 20 - 30%.
А в случае Object, все ключи обязательно попадут в самую быструю форму представления обьекта. In Object Property
Но это уже другая история....
UPD1: поправил пример с JSON.parse. Там при копировании почему то пропали кавычки.
#array #opti #perf #tips
1] Если Ваш Array имеет фиксированный размер, и при этом его элементы не будут изменяться - смело используйте литеральную форму определения такого обьекта. Например:
var theArr = [1, 2, 3];
2] Если элементы будущего Array будут изменяться, то рекомендуется использовать либо констурктор Array либо его функциональную форму:var theArr = new Array (1, 2, 3);
theArr[0]=7;
таким образом вы избежите ненужной нагрузки на GC, поскольку Ваш Array сразу будет создан из предположения что элементы будет изменяться. Или способ из бонус 2 в конце поста.3] Если Ваш Array может расти в размерах, относительно его начальной формы - то настоятельно рекомендуется об этом позаботиться заранее. То есть инициализировать Array таким образом, чтобы V8 заранее предоставил достаточное колличество слотов для новых элементов. Потому как мы помним, что подобныя операция стоит очень дорого. Тем дороже чем больше наш Array.
4] Настоятельно рекомендуется не делать дырок в Array
var theArr = [1, 2, 3];
theArr[7]=1;
приведет к созданию дырок для элементов с индексами 3,4,5,6. Обработка подобных Array в среднем на 30% медленее чем аналогичных и без дырок.5] Настоятельно рекомендуется в Array держать элементы одного и того же типа:
1. Целые числа в пределе от
-1073741824 до 1073741823
2. Любые прочие числа3. Все прочие типы данных
6] Не забываем что V8 устроен таким образом, что изменив модель представления Array на худшую, к лучшей уже вернуться нельзя. Только пересоздавать Array.
7] Помним что Array по задумке V8 инженеров, предназначен для обработки данных в условиях, когда для одних и тех же данных многократно повторяются одни и теже операции. Для подобных ситуаций внутри V8 и созданы все оптимизации, которые опираются на описание выше.
8] Памятке по аллокации слотов:
var theArr = []; // 0 слотов.
var theArr = Array(); // 4 слота
var theArr = new Array(); // 4 слота
var theArr = Array(10); // Аллокация 10 слотов. Тип HOLEY_SMI_ELEMENTS
var theArr = Array(1,2,3,4,5); // Аллокация 5 слотов под пять элемента БЕЗ COW
var theArr = [1,2,3, 4, 5]; // Аллокация 5 слотов под пять элемента и статус COW
theArr[0]=1; // Копирование 5 элементов в новую область и снятие статуса COW
theArr.push(1); // 6 + 3 + 16 = аллокация 25 слотов, высокая вероятность копирования всех элементов в новую память. Тип PACKED_SMI_ELEMENTS неизменен.
От себя добавлю.
Особенно сильно морочить себе голову для случаев COW не COW нужно только тогда, когда это оказывается внутри кода с сотнями тысяч повторений.
При этом крайне внимательно относится к аллокации новых элементов в массиве. Эта проблема тем больше, чем больше используемый массив.
Бонус:
V8 имеет вторую форму представления Array которая является полным подобием Map и включает ее тогда, когда колличество дырок в массиве превосходит все границы. Например:
var theArr = [1,2,3];
theArr[1073741823]=1;
И бонус 2:Определение данных путем использования JSON.parse является намного более производиетльной формой чем формирование данных при помощи литеральных форм как обьекта так и Array.
Что имеет логичное обоснование и явлется рекомендацией от разработчиков V8: https://v8.dev/blog/cost-of-javascript-2019#json
На данных обьемом около 10 килобайт,выгода от подобной инициализации видна невооруженным взглядом и составляет около 20 - 30%.
var theArr = JSON.parse( `[1, 2, 3, ..... 10 0000]`);При этом в случае Array, только что созданный обьект всегда будет без статуса COW
var theObj = JSON.parse( `{"name" : "murych", "age": 46}`);
А в случае Object, все ключи обязательно попадут в самую быструю форму представления обьекта. In Object Property
Но это уже другая история....
UPD1: поправил пример с JSON.parse. Там при копировании почему то пропали кавычки.
👍10🔥3❤1🐳1