Suite à la question Extension des performances de String.prototype Je suis vraiment intrigué, car simplement ajouter "use strict"
à un String.prototype
la méthode a amélioré les performances 10 fois. Le explication par bergi est court et ne me l'explique pas. Pourquoi il y a une telle différence entre deux méthodes presque identiques, qui ne diffèrent que par "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
En mode strict, le contexte this
n'est pas forcé d'être un objet. Si vous appelez une fonction sur un non-objet, this
sera simplement ce non objet.
En revanche, en mode non strict, le contexte this
est toujours d'abord enveloppé dans un objet s'il ne l'est pas déjà. Par exemple, (42).toString()
premiers tours 42
dans un objet Number
, puis appelle Number.prototype.toString
avec l'objet Number
comme contexte this
. En mode strict, le contexte this
n'est pas modifié et appelle simplement Number.prototype.toString
avec 42
comme this
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 à encapsuler et à décompresser les primitifs string
s en String
encapsuleurs d'objet et inversement. Par contre, la version en mode strict fonctionne directement sur la primitive string
, ce qui améliore les performances.