为什么"使用严格的“;在本例中性能提高了10倍

Why "use strict" improves performance 10x in this example?

本文关键字:性能 10倍 quot 为什么      更新时间:2023-09-26

关于扩展String.prototype性能的问题,我真的很感兴趣,因为仅仅将"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

在严格模式下,this上下文不会被强制为对象。如果你在一个非对象上调用一个函数,那么this就是那个非对象。

相反,在非严格模式中,如果对象还不是对象,则this上下文总是首先包装在对象中。例如,(42).toString()首先将42封装在Number对象中,然后使用Number对象作为this上下文来调用Number.prototype.toString。在严格模式下,this上下文保持不变,只调用Number.prototype.toString42作为this上下文。

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

在您的情况下,非严格模式版本会花费大量时间将原始string包装和展开为String对象包装器并返回。另一方面,严格模式版本直接在基元string上工作,这提高了性能。