Ответ [Часть 3/4]: #array #perf #v8 #opti #mem #COW
В ответе, который шел выше (Часть 1/4 и часть 2/4), намеренно был не указан еще один важный аспект оптимизаций со стороны V8. Связано это было с желанием не дробить рассказ о типах представления, зависящих от данных в Array.
Особый случай, COW.
Каждый из обозначенных ранее тиров, в том числе и HOLEY - имеют особый подтип -
При создании Exotic Object Array - V8 допускает еще одну форму - COW, которая предполагает, что этот Array не будет никогда изменяться. То есть это некоторая статичная форма Array, данные которой всегда будут теми же что и при иницализации, и сам по себе этот Array никогда не изменится.
COW расшифровывается как:
Например:
Например:
Любая литеральная форма связывания Array создает Exeotic Object Array, с типом который отвечает тем данным, которые присутствуют внутри литерала Array. При этом, подобный созданный Array будет иметь статус COW. То есть RunTime будет предполагать что данный Array никогда не будет меняться.
Исключение создание пустого Array:
На что влияет флаг COW:
Подобный обьект занимает наименьший обьем памяти в сравнении с аналогичным. И получит особый род оптимизаций на уровне машинного кода, которые будут предполагать, что этот Array никогда не будет изменен. То есть вплоть до извлечения константных значений из Array и подстановки их в код вместо прямого полноценного обращения обьекту по его ключу.
При этом, любая попытка изменить подобный обьект, приведет к снятию флага COW, и пересозданию оригинального обьекта заново. Что требует дополнительных ресурсов.
Например:
Выводы про COW
Иными словами, когда мы знаем, что наш Array имеет какие то базовые значения, и мы знаем что этот Array будет изменяться, то правильной формой обьявления его, для случая V8 будет:
new Array ( 1,2,3);
Если же мы уверены в том, что Array который нам требуется, не будет притерпевать никаких изменений, то есть сохранит свою форму и данные ровно такими как при инициализации - то мы должны использховать литеральную форму создания Array
[1, 2, 3];
так как в этом случае мы получим дополнительные оптимизации как по памяти, так и с точки зрения манипуляции обьектом, которые будут исходить из предположения, что этот Array никогда не изменится.
В ответе, который шел выше (Часть 1/4 и часть 2/4), намеренно был не указан еще один важный аспект оптимизаций со стороны V8. Связано это было с желанием не дробить рассказ о типах представления, зависящих от данных в Array.
Особый случай, COW.
Каждый из обозначенных ранее тиров, в том числе и HOLEY - имеют особый подтип -
COW
.При создании Exotic Object Array - V8 допускает еще одну форму - COW, которая предполагает, что этот Array не будет никогда изменяться. То есть это некоторая статичная форма Array, данные которой всегда будут теми же что и при иницализации, и сам по себе этот Array никогда не изменится.
COW расшифровывается как:
Copy On Write
. Скопировать в случае записи.Например:
var theArr = [1, 2, 3]; // PACKED_SMI_ELEMENTS (COW);при этом стоит изменить любой из элементов, или добавить элемент, или удалить элемент, как статус COW будет анулирован.
var theArr = [1, 2, , 4]; // HOLEY_SMI_ELEMENTS (COW);
var theArr = ["lorem", 2]; // HOLEY_ELEMENTS (COW);
Например:
var theArr = [1, 2, 3]; // PACKED_SMI_ELEMENTS (COW);
theArr[0] = 2; // PACKED_SMI_ELEMENTS;
var theArr = ["lorem", 2]; // HOLEY_ELEMENTS (COW);
theArr.pop(); // HOLEY_ELEMENTS
но при этом:var theArr = new Array(1, 2, 3); //PACKED_SMI_ELEMENTS без COW
var theArr = new Array(3); // HOLEY_SMI_ELEMENTS без COW
COW
- это особая форма представления Array, которая по сути является самой быстрой. То есть когда я вначале рассказывал о том, что PACKED_SMI_ELEMENTS
это наш наиглавнейший ориентир - я намеренно соврал. И сделал это для того, чтобы вначале не сбивать с толку этим особым случаем, когда только что созданный при помощи литеральной формы Array получает особый статус COW. var theArr = [1, 2, 3]; // PACKED_SMI_ELEMENTS (COW);Но точно такой же Array созданный при помощи конструктора, подобного статуса не получает.
var theArr = new Array(1, 2, 3); //PACKED_SMI_ELEMENTSПромежуточный итог:
var theArr = []; //PACKED_SMI_ELEMENTS
Любая литеральная форма связывания Array создает Exeotic Object Array, с типом который отвечает тем данным, которые присутствуют внутри литерала Array. При этом, подобный созданный Array будет иметь статус COW. То есть RunTime будет предполагать что данный Array никогда не будет меняться.
Исключение создание пустого Array:
var theArr = [];
Любая форма создания Array при помощи конструктора Array ( new Array( [...] ) ); будет приводить к созданию обьекта, представление которого будет базироваться на данных из которых создавался обьект, но при этом особого флага COW установлено не будет. То есть RunTime будет предполагать, что подобный Array будет изменяться.На что влияет флаг COW:
Подобный обьект занимает наименьший обьем памяти в сравнении с аналогичным. И получит особый род оптимизаций на уровне машинного кода, которые будут предполагать, что этот Array никогда не будет изменен. То есть вплоть до извлечения константных значений из Array и подстановки их в код вместо прямого полноценного обращения обьекту по его ключу.
При этом, любая попытка изменить подобный обьект, приведет к снятию флага COW, и пересозданию оригинального обьекта заново. Что требует дополнительных ресурсов.
Например:
var theArr = [1, 2, 3]; // PACKED_SMI_ELEMENTS (COW);
theArr[0]=2; // Будет
полностью пересоздан в памяти обьект theArr без флага COW. Выводы про COW
Иными словами, когда мы знаем, что наш Array имеет какие то базовые значения, и мы знаем что этот Array будет изменяться, то правильной формой обьявления его, для случая V8 будет:
new Array ( 1,2,3);
Если же мы уверены в том, что Array который нам требуется, не будет притерпевать никаких изменений, то есть сохранит свою форму и данные ровно такими как при инициализации - то мы должны использховать литеральную форму создания Array
[1, 2, 3];
так как в этом случае мы получим дополнительные оптимизации как по памяти, так и с точки зрения манипуляции обьектом, которые будут исходить из предположения, что этот Array никогда не изменится.
👍7❤1