Страницы

Поиск по вопросам

суббота, 7 декабря 2019 г.

Почему “use strict” повышает производительность в 10 раз в этом примере?

#javascript #производительность


После вопроса Расширение String.prototype показывает производительно ниже вызова
функции в 10 раз мне стало интересно, почему простое добавление "use strict" в метод
String.prototype повышает производительность в 10 раз. Объяснение, данное Bergi, слишком
короткое и непонятное.

Почему такое резкое различие в производительности между двумя почти идентичными методами,
единственное отличие между которыми — только "use strict" в начале? Вы можете объяснить
подробнее и с обоснованием?



  

String.prototype.count = function(char) {
  var n = 0;
  for (var i = 0; i < this.length; i++)
    if (this[i] == char) n++;
  return n;
};

String.prototype.count_strict = function(char) {
  "use strict";
  var n = 0;
  for (var i = 0; i < this.length; i++)
    if (this[i] == char) n++;
  return n;
};
// Here is how I measued speed, using Node.js 6.1.0

var STR = '0110101110010110100111010011101010101111110001010110010101011101101010101010111111000';
var REP = 1e4;

console.time('proto');
for (var i = 0; i < REP; i++) STR.count('1');
console.timeEnd('proto');

console.time('proto-strict');
for (var i = 0; i < REP; i++) STR.count_strict('1');
console.timeEnd('proto-strict');
  


  

Результат:  

proto: 101 ms  
proto-strict: 7.5 ms  


Перевод вопроса «Why “use strict” improves performance 10x in this example?» @exebook.
    


Ответы

Ответ 1



Режим "use strict" не обязывает this контекст быть объектом. Если Вы вызовете функцию для не объекте, то this останется тем не объектом. И напротив, в не строгом режим this контекст всегда вначале оборачивается в объект, если он ещё не объект. Например, (42).toString() сначала обертывает 42 в объект Number, а уже затем вызывает Number.prototype.toStringс объектом Number в контексте this. В строгом режиме контекст this остается нетронутым и просто вызывается Number.prototype.toString с 42 в контексте this. (function() { console.log(typeof this); }).call(42); // 'object' (function() { 'use strict'; console.log(typeof this); }).call(42); // 'number' В Вашем случае нестрогая версия режима тратит много времени на перенос и разворачивание примитива string в String и обратно. С другой стороны, строгий режим непосредственно непосредственно работает с примитивом string, что и повышает производительность. Перевод ответа «Why “use strict” improves performance 10x in this example?» @Mattias Buelens.

Комментариев нет:

Отправить комментарий