Производительность оператора прототипа Javascript: экономит память, но разве это быстрее?

Я прочитал здесь (Дуглас Крокфорд) , используя оператор-прототип для добавления методов в классы Javascript , экономит также память .

Затем я прочитал в эту статью Джона Резига «Создание функции со множеством свойств прототипа - очень, очень, быстро » , но он говорит об использовании прототипа стандартным способом, или он говорит о своем конкретном примере в своей статье?

Например, создает ли этот объект:

function Class1()
{
   this.showMsg = function(string) { alert(string); }
}
var c = new Class1();
c.showMsg();

медленнее, чем создание этого объекта, тогда?

function Class1() {}
Class1.prototype.showMsg = function(string) { alert(string); }
var c = new Class1();
c.showMsg();

PS

Я знаю, что прототип используется для создания объекта наследования, одноэлементного объекта и т. Д. Но этот вопрос не имеет ничего общего с этими субъектами.


РЕДАКТИРОВАТЬ: кому он также может быть интересен для сравнения производительности между JS object и JS static objet могут прочитать этот ответ ниже . Статические объекты определенно быстрее , очевидно, их можно использовать только тогда, когда вам не нужно более одного экземпляра объекта.

48
задан Community 23 May 2017 в 12:32
поделиться

3 ответа

Это был интересный вопрос, поэтому я провел несколько очень простых тестов (мне следовало перезапустить браузеры, чтобы очистить память, но я этого не сделал; считайте, что это того стоит). Похоже, что по крайней мере в Safari и Firefox prototype работает значительно быстрее [edit: не в 20 раз, как говорилось ранее]. Я уверен, что реальный тест с полнофункциональными объектами был бы лучшим сравнением. Код, который я прогнал, выглядел так (я прогнал тесты несколько раз, по отдельности):

var X,Y, x,y, i, intNow;

X = function() {};
X.prototype.message = function(s) { var mymessage = s + "";}
X.prototype.addition = function(i,j) { return (i *2 + j * 2) / 2; }

Y = function() {
    this.message = function(s) { var mymessage = s + "";}
    this.addition = function(i,j) { return (i *2 + j * 2) / 2; }
};


intNow = (new Date()).getTime();
for (i = 0; i < 1000000; i++) {
    y = new Y();
    y.message('hi');
    y.addition(i,2)
}
console.log((new Date()).getTime() - intNow); //FF=5206ms; Safari=1554

intNow = (new Date()).getTime();
for (i = 0; i < 1000000; i++) {
    x = new X();
    x.message('hi');
    x.addition(i,2)
}
console.log((new Date()).getTime() - intNow);//FF=3894ms;Safari=606

Это очень обидно, потому что я действительно ненавижу использовать prototype. Мне нравится, когда мой объектный код самоинкапсулируется, и ему не дают дрейфовать. Однако, когда важна скорость, у меня нет выбора. Черт.

[Edit] Большое спасибо @Kevin, который указал, что мой предыдущий код был неправильным, что дало огромный толчок к заявленной скорости метода prototype. После исправления прототип по-прежнему работает значительно быстрее, но разница уже не такая огромная.

60
ответ дан 26 November 2019 в 18:42
поделиться

Я уверен, что создание экземпляра объекта намного быстрее и потребляет меньше памяти, в этом нет никаких сомнений, но я бы подумал, что движку javascript нужно перебрать все свойства объекта, чтобы определить, является ли вызываемое свойство / метод частью этого объекта, а если нет, то проверьте прототип. Я не уверен в этом на 100%, но предполагаю, как это работает, и если да, то в НЕКОТОРЫХ случаях, когда к вашему объекту добавлено МНОГО методов, созданных только один раз и интенсивно используемых, тогда это может быть немного медленнее, но это всего лишь предположение, что я ничего не тестировал.

Но, в конце концов, я все же согласен с тем, что, как правило, использование прототипа будет быстрее.

0
ответ дан 26 November 2019 в 18:42
поделиться

Интуитивно кажется, что было бы более эффективно с точки зрения памяти и быстрее создавать функции на прототипе: функция создается только один раз, не каждый раз, когда создается новый экземпляр.

Однако будет небольшая разница в производительности, когда придет время получить доступ к функции. При ссылке на c.showMsg среда выполнения JavaScript сначала проверяет свойство на c . Если он не найден, проверяется прототип c .

Таким образом, создание свойства в экземпляре приведет к несколько более быстрому доступу, но это может быть проблемой только для очень глубокой иерархии прототипов.

3
ответ дан 26 November 2019 в 18:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: