关于javascript:严格模式更高效吗?

Is strict mode more performant?

在"严格模式"下在浏览器中执行javascript是否通常会使其更具性能?是否有任何一个主要的浏览器进行了额外的优化,或者使用了任何其他可以在严格模式下提高性能的技术?

稍微重新表述一下,严格模式除了其其他目标外,是否允许浏览器引入额外的优化或其他性能增强?


Is strict mode intended, amongst its other goals, to allow browsers to introduce additional optimisations or other performance enhancements?

尽管我认为答案是肯定的,但我不确定它是否打算这样做。

但我可以肯定地说,严格的模式确实提供了这些机会,浏览器将实现这些机会——不管提供这些机会是否是ECMA委员会的故意目标。但是,我不希望所有这些机会都能立即得到。在许多情况下,准则可能是先正确,后性能,因为严格模式目前尚未广泛使用。(我在Mozilla的JavaScript引擎上工作,已经实现了严格模式的各个部分,我们将其作为一个一般规则来实现——尽管如果我尝试的话,我可能会想到一两个异常。)


严格模式实际上不是关于性能的,它是一种严格的语言变体,其主要目标是避免被认为是容易出错的特性。

基本上,它的目标是使语言更安全,引入了大量的语义变化,还进行了额外的错误检查,并且错误是嘈杂的,在非严格的代码中,事情只会默默地失败。

关于性能,我认为浏览器厂商现在很难实现严格模式,问题是JS引擎大多是基于ECMAScript 3的,实现严格模式并不容易,因为严格的范围非常灵活,可以混合非严格和严格的代码。

参见:

  • ECMAScript 5严格模式、JSON等
  • 蜘蛛猴严格模式票
  • WebKit严格模式票据


根据这个测试,"严格模式"可以快25%左右。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  Q


  Q


  Benchmark.prototype.setup = function() {
    function d(i) {
      var x = '999';
      y = eval("y = 8;");
      var z = x + y + i;
      document.getElementById('a').innerHTML = z;
    }

    function c(i) {
      'use strict'
      var x = '999';
      var y = eval("y = 8;");
      var z = x + y + i;
      document.getElementById('b').innerHTML = z;
    }
  };

可以在这里测试:http://jspef.com/strict-mode/严格模式有趣的是,在"严格模式"下,参数数组的操作速度可以快6倍左右!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  Benchmark.prototype.setup = function() {
    var nonstrict = (function() {
        return function (arg1) {
            var index;
            for (index = 1; index < arguments.length; ++index) {
                arguments[0] += arguments[index];
            }
            return arguments[0] - arg1;
        };
    }());
    var strict = (function() {
       "use strict";
        return function (arg1) {
            var index;
            for (index = 1; index < arguments.length; ++index) {
                arguments[0] += arguments[index];
            }
            return arguments[0] - arg1;
        };
    }());
    var result;
  };

下面是jspef测试:http://jspef.com/strict-mode-arguments


在大多数情况下,没有。如果仔细检查ECMAScript 5标准文档,您会发现伪代码算法中几乎所有出现的严格模式都是:

1
2
3
4
5
6
  if (isStrictMode) {
      //throw an (early) SyntaxError or TypeError
  }
  else {
      //return
  }

有两件事要注意:

  • ECMAScript 3中不存在对严格模式的检查。虽然它相对较轻,但与EcmaScript 3的对应版本相比,符合规范的JavaScript实现现在至少运行了一个额外的条件检查。是的……我知道这样的一次检查只需要很少的时钟周期,但总的来说没什么。
  • 因为strict模式主要是javascript的一个解析时间特性,所以当为某些网站(如sunspider)启用strict模式时,您最喜欢的浏览器不会显示出很大的性能下降。也就是说,性能下降发生在代码执行之前,这意味着最终用户可以感觉到它,但使用日期对象测量块执行时间在很大程度上是无法测量的。