严格模式是否表现更好?


74

一般而言,在“严格模式”下在浏览器中执行javascript是否会提高性能?是否有任何主流浏览器都进行了其他优化或使用了其他技术来提高严格模式下的性能?

稍微改一下,严格模式是否旨在(除其他目标外)允许浏览器引入其他优化或其他性能增强功能?


哪些浏览器现在都支持ECMAScript 5?
Jamie Wong 2010年



3
@Matthew:很好的链接!@ sje397:该列表上唯一完整的ECMAScript 5实现是BESEN(也从未听说过),并且其主页上记录了以下内容:“严格代码的运行速度比非严格代码快,因此,请在以下位置使用“严格”有可能”
Crescent Fresh

2
IIRC道格拉斯·克罗克福德(Douglas Crockford)在这次谈话中声称,该with关键字不仅效果不佳,而且仅在语言中使用也会使整个语言变慢。CMS答案中的此链接表示,该with关键字在严格模式下不起作用,因此,这似乎至少表明有可能提速。
MatrixFrog 2011年

Answers:


25

除其他目标外,严格模式是否旨在允许浏览器引入其他优化或其他性能增强功能?

不管是不是有人打算这样做,我不知道,但我想答案是肯定的。

但是我可以肯定地说,严格模式确实提供了这些机会,而浏览器会实现这些机会-不管提供这些机会是否是ECMA委员会的故意目标。但是,我不希望所有这些机会会立即被抓住。在许多情况下,该咒语可能首先是正确的,然后是性能,因为严格的模式目前尚未广泛使用。(我在Mozilla的JavaScript引擎上工作,并已实现严格模式的各个部分,我们通常以这种方式来实现它-尽管我尝试过可能会想到一两个异常。


4
是的,严格模式的设计目标是启用词法作用域(这就是禁用with之类的原因)的原因。从第一天开始就是这个意图。
本杰明·格伦鲍姆

22

严格的模式是不是真正的性能,它严格变种的语言,它的主要目标是避免了被认为是容易出错的功能

基本上,它的目标是使语言更安全,引入很多语义上的更改,还进行附加的错误检查,并且错误很嘈杂,在非严格代码中,事物只会默默地失败。

关于性能,我认为浏览器供应商现在很难实施严格模式,问题在于JS引擎主要基于ECMAScript 3,并且实施严格模式并不容易,因为严格的范围非常灵活,您可以混合使用非严格代码和严格代码。

也可以看看:


+1的链接。我不太明白那第三句话与表现有什么关系。
sje397 2010年

4
这里开始(似乎是可信的):“约翰[Resig]没有提到的是严格模式可能会带来更高的性能。如果浏览器被告知“我声明此代码正确无误”,则可以减少处理歧义的时间,并着手开展业务。
sje397 2010年

@ sje397:strict模式的另一个好处是,如果一个函数声明了一个局部变量foo并且没有定义任何捕获它的嵌套函数,则它将foo在第一次读取之前将一个数字存储到,而从不将数字以外的任何东西存储到中foo,调用函数(或其他任何函数)不可能导致foo保留数字以外的任何东西。确定上述条件成立很容易,并且使用数字的处理比使用碰巧是数字的多态对象的处理要容易得多。
超级猫

14

根据此测试,“严格模式”可以快25%。

<div id="a">
  Q
</div>
<div id="b">
  Q
</div>
<script>
  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;
    }
  };
</script>

可以在这里测试:http : //jsperf.com/strict-mode


有趣的是,在“严格模式”下,对arguments数组的操作可以快大约6倍!

<script>
  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;
  };
</script>

这是jsPerf测试:http ://jsperf.com/strict-mode-arguments


2
在我的Chrome浏览器中,2017年的今天,非严格版本分别比基准测试中的严格版本慢15%和70%。我想这意味着性能差异比以前要小,但仍然很明显。知道导致这些性能差异的原因是什么?
John Slegers

4

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

  if (isStrictMode) {
      //throw an (early) SyntaxError or TypeError
  }
  else {
      //return
  }

有两件事要注意:

  1. ECMAScript 3中不存在对严格模式的检查。尽管它比较轻巧,但与ECMAScript 3对应版本相比,符合JavaScript的实现现在至少运行了一项额外的条件检查。是的...我知道像这样的单个检查会消耗很少的时钟周期,但累加起来很少
  2. 因为严格模式主要是JavaScript的解析时间功能,所以当某些网站(例如SunSpider)启用了严格模式时,您最喜欢的浏览器不会表现出很大的性能下降。即,会发生性能劣化之前被执行的代码的这意味着它可以是可感知的给最终用户,但在很大程度上是无法估量的使用日期对象来测量块的执行时间

2
但是您怎么知道例如v8没有利用严格模式进行额外的优化呢?
UpTheCreek

6
除其他事项外,我还为Internet Explorer 10进行了性能测试“严格模式”。我能提供给您的最好的例子是,如果您有两个完全相同的大型JavaScript文件,没有严格的模式违规,并且其中只有一个包含“ use strict”,那么没有该文件的文件将运行得更快,因为它没有运行严格的模式检查。仅仅因为您在严格模式下删除了对“ with”的支持,并不意味着您可以从解析器中彻底删除它(仍然必须在非严格情况下允许它)。不,相反,您的DLL大小实际上随着执行时间的增加增加
戴夫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.