V8 разработчик здесь. TL; DR: лучшее, что вы можете сделать с «упакованными элементами», это не беспокоиться о них. Разница почти никогда не измерима.
В некоторых микробенчмарках, где в оптимизированном коде для цикла с горячим ядром есть только несколько машинных инструкций, каждая отдельная инструкция имеет значение, и если проверка «дыры» для текущего элемента является одной из них (фактически два : cmp
+ je
на x86), то отслеживание того, какие массивы не нужны, может повлиять на результат теста. Но в реальных приложениях, где вы выполняете нетривиальные операции над элементом массива, влияние двух машинных инструкций не измеримо. Любые искажения, с которыми вы сталкиваетесь с помощью своего пользовательского класса-оболочки, скорее всего, стоят дороже, чем незначительные накладные расходы, которые вы могли бы сэкономить.
Конкретный вопрос, который вы задаете, можно решить, выбрав композицию "has-a" вместо "is-a":
class PackedArray {
extend(values) {
this.#data = this.#data.concat(values);
}
get(i) { return this.#data[i]; }
#data = [];
}
Что также решит проблему, связанную с тем, что в подклассе код все еще может использовать my_packed_array[10000] = "now you have holes"
для обхода метода .extend()
. Однако имейте в виду то, что я написал выше: результат проверки дырки крошечный , и любая из этих дополнительных упаковок, вероятно, стоит намного больше, чем экономит.
РЕДАКТИРОВАТЬ: то, что пишет @MathiasBynens, также является очень хорошим моментом: не оптимизируйте для V8, пусть V8 оптимизирует для вас! : -)