Ответ [Часть 4/4]: #array #perf #v8 #opti #mem
Сведение воедино всего что сказано в частях с 1 по 3
Создание Array при помощи пустого литерала,
То есть не будет иметь ни одного подготовленного слота для элементов.
Обратите внимание, что в это случае Array не создается в форме COW.
Создание Array при помощи литерала с одним и более элементов
Создание exotic object Array, при помощи литерала содержащего минимум один элемент, приводит к созданию Array с особым флагом COW. В этом случае RunTime при оптимизации отталкивается от мысли, что подобный Array статичен, и никогда более меняться не будет.
Что логично, если вспомнить насколько часто в JS принято в коде писать что-то наподобие:
Любые манипуляции с Array созданным литералом, приводят к копированию всех элементов обьекта Array в новое место в куче уже без флага COW.
произошло полное копирование всех элементов изначального Array, плюс выделение дополнительных 19 - слотов предполагая что Array будет рости.
Другой пример:
Создание Array при помощи конструrтора new Array() или функции Array();
А теперь про выделение слотов под элементы, то есть фактически аллокация памяти:
При обращении к элементу выше существующей границы ( Например для Array() это будет индекс 4) происходит выделение дополнительных слотов по формуле:
Длина массива с уже добавленным элементом + 50% от этой длины + 16
Например:
Длина массива после добавления элемента: 5
50% от этой длины: 5/2 = 2.5 => 3
+16
Итого:
5 + 3 + 16 = 24 элемента.
Каждый элемент занимает от 4 байт для 32 битных систем и 8 байт для 64 битных.
При этом важно помнить, что при алокации новых слотов, если необходимого обьема памяти непосредственно за предыдущим блоком не будет - то это приведет к полному копированию всех элементов в новую область памяти.
Выводом из этого всего идет очень простой тезис - чем меньше аллокаций тем лучше.
То есть нужно планировать размеры массивов в том случае, если они могут расти.
При этом, чем больше массив, тем дороже будет операция аллокации новых элементов.
Сведение воедино всего что сказано в частях с 1 по 3
Создание Array при помощи пустого литерала,
var theArr = []; //
<FixedArray[4]> [PACKED_SMI_ELEMENTS]
при этом будет создана только базовая структура обьекта Array, который будет ссылаться на стандартную заглушку. То есть не будет иметь ни одного подготовленного слота для элементов.
Обратите внимание, что в это случае Array не создается в форме COW.
Создание Array при помощи литерала с одним и более элементов
Создание exotic object Array, при помощи литерала содержащего минимум один элемент, приводит к созданию Array с особым флагом COW. В этом случае RunTime при оптимизации отталкивается от мысли, что подобный Array статичен, и никогда более меняться не будет.
Что логично, если вспомнить насколько часто в JS принято в коде писать что-то наподобие:
new Map( [ ["a", 1], ["b" 2] ] );То есть V8 в первую очередь нацелен на то, чтобы максимально оптимизировать работу с подобными синтаксическими конструкциями, где литеральная форма массива используется как какой-то промежуточный код.
Любые манипуляции с Array созданным литералом, приводят к копированию всех элементов обьекта Array в новое место в куче уже без флага COW.
var theArr = [1, 2, 3]; //0x340b00267491 <FixedArray[3]> [PACKED_SMI_ELEMENTS (COW)]
theArr.push(2); //0x340b0012ba81 <FixedArray[22]> [PACKED_SMI_ELEMENTS]
произошло полное копирование всех элементов изначального Array, плюс выделение дополнительных 19 - слотов предполагая что Array будет рости.
Другой пример:
var theArr = [1, 2, 3]; //0x340b00267491 <FixedArray[3]> [PACKED_SMI_ELEMENTS (COW)]в этом случае, был просто пересоздан Array с копированием всех 3 элементов. Дополнительные слоты не создавались.
theArr[0]=1; 0x340b0012be69 <FixedArray[3]> [PACKED_SMI_ELEMENTS]
Создание Array при помощи конструrтора new Array() или функции Array();
var theArr= new Array(); // <FixedArray[4]> [PACKED_SMI_ELEMENTS]
var theArr=Array();
// <FixedArray[4]> [PACKED_SMI_ELEMENTS]
при этом, в отличии от Array созданного при помощи пустого литерала, обьект Array будет сразу содержать 4 подготовленых слота для элементов. А теперь про выделение слотов под элементы, то есть фактически аллокация памяти:
При обращении к элементу выше существующей границы ( Например для Array() это будет индекс 4) происходит выделение дополнительных слотов по формуле:
Длина массива с уже добавленным элементом + 50% от этой длины + 16
Например:
var theArr = [1, 2, 3];Будет алоцировано 24 элемента:
theArr[5]=1;
Длина массива после добавления элемента: 5
50% от этой длины: 5/2 = 2.5 => 3
+16
Итого:
5 + 3 + 16 = 24 элемента.
Каждый элемент занимает от 4 байт для 32 битных систем и 8 байт для 64 битных.
При этом важно помнить, что при алокации новых слотов, если необходимого обьема памяти непосредственно за предыдущим блоком не будет - то это приведет к полному копированию всех элементов в новую область памяти.
Выводом из этого всего идет очень простой тезис - чем меньше аллокаций тем лучше.
То есть нужно планировать размеры массивов в том случае, если они могут расти.
При этом, чем больше массив, тем дороже будет операция аллокации новых элементов.
👍10
Обобщенный набор рекомендаций по работе с 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
As For JS
https://www.youtube.com/live/fQ7_GT8_zeM?feature=share
Более короткая версия видео о работе this в языке JavaScript.
Но настоятельно рекомендуем, перед этим, просмотреть предыдущее, более подробное видео о работе this в JavaScript.
Но настоятельно рекомендуем, перед этим, просмотреть предыдущее, более подробное видео о работе this в JavaScript.
❤3
Я все время стараюсь отсматривать новые видео на YouTube связанные с JS тематикой.
И вот сегодня, видимо совпадение, а может быть это алгоритмы youtube так работают, мне подсунули видео, какой-то it школы, где идет лекция о том, что такое this.
То, что там this описан совершенно не верно - и так понятно. Но я услышал нечто новое - со слов лектора, обьект заданный в литеральной форме не имеет своего собственного this.
Вот таких откровений я вообще не ожидал.
А люди в этой школе платят деньги за обучение.
https://www.youtube.com/watch?v=G18mcIoEL0s
И вот сегодня, видимо совпадение, а может быть это алгоритмы youtube так работают, мне подсунули видео, какой-то it школы, где идет лекция о том, что такое this.
То, что там this описан совершенно не верно - и так понятно. Но я услышал нечто новое - со слов лектора, обьект заданный в литеральной форме не имеет своего собственного this.
Вот таких откровений я вообще не ожидал.
А люди в этой школе платят деньги за обучение.
https://www.youtube.com/watch?v=G18mcIoEL0s
🤡4👌2
До JS сообщества наконец начинает доходить то, что я рассказываю уже лет 7.
Одни переиздают книжки, скромно исправляя глупости написаные рание.
Другие выпускают вот такие статьи.
А третьи уже сделали платные курсы с секретными знаниями о том как работает JS.
Где, ой какая новость, нет переменных.
Где, ой как неудобно вышло, идентификаторы — єто только метки(ссылки).
И т.д. Это статья из очень популярной ленты новостей о JS.
https://www.joshwcomeau.com/javascript/the-const-deception/
Одни переиздают книжки, скромно исправляя глупости написаные рание.
Другие выпускают вот такие статьи.
А третьи уже сделали платные курсы с секретными знаниями о том как работает JS.
Где, ой какая новость, нет переменных.
Где, ой как неудобно вышло, идентификаторы — єто только метки(ссылки).
И т.д. Это статья из очень популярной ленты новостей о JS.
https://www.joshwcomeau.com/javascript/the-const-deception/
Joshwcomeau
The “const” Deception • Josh W. Comeau
The “const” keyword in JavaScript is used to create constants, variables that can't change. Curiously, though, we do seem to be able to edit objects and arrays that are created using “const”. In this tutorial, we're going to dig into the incredibly-important…
🔥5👍2🐳1
Всего 15 минут.
https://www.youtube.com/watch?v=98mOkxRFHYA
https://www.youtube.com/watch?v=98mOkxRFHYA
YouTube
⎡msk⎦ JavaScript Destructuring Assignment или не все то золото что коротко пишется.
Подводные камни деструктурирующего присваивания.
Открываем для себя факт того, что использование Destructuring Assignment для ArrayAssignmentPattern, строго в соответствии со спецификацией, обойдется Вам как два мешка картошки.
Telegram канал: https:/…
Открываем для себя факт того, что использование Destructuring Assignment для ArrayAssignmentPattern, строго в соответствии со спецификацией, обойдется Вам как два мешка картошки.
Telegram канал: https:/…
🔥10
2023-05-24_04-47-21.mkv
285.3 MB
⎡Ukr⎦ Читання "JavaScript - для дітей" (бородатих),
або намагання Мурича опановувати Солов'їну
Ігноруйте це. Бо там мало чого є корисного. ( доки що)
Вступ.
_господи, вибачте мені це знущання_
або намагання Мурича опановувати Солов'їну
Ігноруйте це. Бо там мало чого є корисного. ( доки що)
Вступ.
_господи, вибачте мені це знущання_
❤6👍2👀2