1. ホーム
  2. javascript

[解決済み] なぜ "use strict "はパフォーマンスを10倍向上させるのか?

2022-07-07 13:03:16

疑問点

質問に続く String.prototypeの性能を拡張する 私は本当に興味をそそられます。 "use strict"String.prototype メソッドに変更することで、パフォーマンスが10倍向上しました。その 説明 によって ベルギ は短いし、私には説明になっていない。ほとんど同じ手法でありながら、なぜこのような劇的な違いがあるのでしょうか。 "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

どのように解決するのですか?

ストリクトモードでは this コンテキストがオブジェクトであることは強制されません。 オブジェクトでない関数を呼び出すと this はその非オブジェクトになるだけです。

これに対して、非厳格モードでは this コンテキストは、まだオブジェクトでない場合は常に最初にオブジェクトにラップされます。例えば (42).toString() が最初にラップされます。 42Number オブジェクトを作成し、次に 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'

あなたの場合、非ストライクトモード版では、プリミティブのラップとアンラップに多くの時間を費やし stringString オブジェクトのラッパーに変換して返します。一方、ストリクトモード版は、直接プリミティブな string を直接扱うので、パフォーマンスが向上します。