Я задавался вопросом, должно ли использование прототипов в JavaScript быть большей памятью, эффективной, чем присоединение каждого члена объекта непосредственно к нему по следующим причинам:
По сравнению с:
Я запустил немного эксперимента с этим:
var TestObjectFat = function()
{
this.number = 42;
this.text = randomString(1000);
}
var TestObjectThin = function()
{
this.number = 42;
}
TestObjectThin.prototype.text = randomString(1000);
randomString(x)
просто производит, ну, в общем, случайную строку длины x.
Я затем инстанцировал объектов в больших количествах как это:
var arr = new Array();
for (var i = 0; i < 1000; i++) {
arr.push(new TestObjectFat()); // or new TestObjectThin()
}
и проверенный использование памяти процесса браузера (Google Chrome). Я знаю, это не очень точно...
Однако в обоих случаях использование памяти повысилось значительно как ожидалось (приблизительно 30 МБ для TestObjectFat
), но опытный вариант, используемый не намного меньше памяти (приблизительно 26 МБ для TestObjectThin
).
Я также проверил что TestObjectThin
экземпляры содержат ту же строку в своем "текстовом" свойстве, таким образом, они действительно используют свойство прототипа.
Теперь, я не так уверен, что думать об этом. Разработка прототипа, кажется, не большое средство сохранения памяти вообще.
Я знаю, что разработка прототипа является прекрасной идеей по многим другим причинам, но я конкретно обеспокоен использованием памяти здесь. Какие-либо объяснения, почему опытный вариант использует почти тот же объем памяти? Я пропускаю что-то?
Ваш тест является подозрительным - выделение объектов JavaScript сопряжено со значительными накладными расходами, что, вероятно, исказит ваши результаты. Если вы вставите большие блоки данных в свой класс-прототип, это может дать больший выигрыш.
К сожалению, использование памяти в JavaScript сложно контролировать, особенно когда задействован JIT (представлены ли ваши JIT-методы в модели использования памяти? И т. Д.).
В обоих случаях вы создали 1000 объектов, и объект намного тяжелее в памяти, чем строка. Thin vs Fat представляет собой набор на 999 струн. Итак, предположим, что создание объекта (даже простого) стоит 26k, а создание строки шириной 1000 символов стоит 4k. Тогда ваше наблюдение прекрасно объяснено.
Fat = 1000 * 26Ko + 1000 * 4Ko = 30Mo
Thin = 1000 * 26Ko + 4Ko = 26Mo