127 votes

Pourquoi "use strict" améliore les performances de 10x dans cet exemple ?

Suite à la question Extension des performances de String.prototype Je suis vraiment intriguée, parce que le simple fait d'ajouter "use strict" à un String.prototype a permis de décupler les performances. Le site explication par bergi est court et ne m'explique pas tout. Pourquoi il y a une telle différence entre deux méthodes presque identiques, qui ne diffèrent que par le fait qu'elles ne sont pas identiques ? "use strict" au sommet ? Pouvez-vous expliquer plus en détail et avec la théorie derrière cela ?

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');

Résultat :

proto: 101 ms
proto-strict: 7.5 ms

155voto

Mattias Buelens Points 7690

En mode strict, le this Le contexte n'est pas obligé d'être un objet. Si vous appelez une fonction sur un non-objet, this sera juste ce non-objet.

En revanche, en mode non strict, la this Le contexte est toujours d'abord enveloppé dans un objet s'il n'est pas déjà un objet. Par exemple, (42).toString() premiers emballages 42 dans un Number et appelle ensuite Number.prototype.toString avec le Number en tant qu'objet this contexte. En mode strict, le this n'est pas modifié et appelle simplement Number.prototype.toString con 42 comme this le contexte.

(function() {
  console.log(typeof this);
}).call(42); // 'object'

(function() {
  'use strict';
  console.log(typeof this);
}).call(42); // 'number'

Dans votre cas, la version en mode non strict passe beaucoup de temps à emballer et à désemballer les primitives. string dans String et retour. La version en mode strict, quant à elle, travaille directement sur la primitive string ce qui améliore les performances.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X