【问题标题】:Is strict mode more performant?严格模式是否更高效?
【发布时间】:2011-03-09 22:13:54
【问题描述】:

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

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

【问题讨论】:

  • 现在有哪些浏览器支持 ECMAScript 5?
  • @Matthew:很好的链接! @sje397:该列表中唯一完整的 ECMAScript 5 实现是 BESEN(也从未听说过),它的主页指出以下内容:“严格代码比非严格代码运行得更快,因此请最好使用“使用严格”,其中有没有可能”
  • IIRC Douglas Crockford 声称 somewhere in this talk 关键字 with 不仅表现不佳,而且只是 在语言中使用它 会使整个语言变慢。 This link 来自 CMS 的回答说 with 关键字在严格模式下不起作用,因此这似乎至少表明 潜在 可以加快速度。

标签: javascript


【解决方案1】:

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

是否有意这样做,我不确定,但我认为答案是肯定的。

但我可以肯定地说,严格模式确实提供了这些机会,并且浏览器会实现它们——无论提供这些机会是否是 ECMA 委员会的有意目标。但是,我不希望所有这些机会都会立即被利用。在许多情况下,口头禅可能首先是正确性,然后是性能,因为严格模式目前还没有被广泛使用。 (我在 Mozilla 的 JavaScript 引擎上工作,并且已经实现了严格模式的各个部分,我们将这种方式作为一般规则来实现——尽管如果我尝试过,我可能会想到一两个例外。)

【讨论】:

  • 是的,严格模式的设计目标是启用词法作用域(这就是禁用 with 之类的东西的原因)。这是从第一天开始的意图。
【解决方案2】:

严格模式与性能无关,它是语言的strict variant,其主要目标是避免被认为是错误- 容易出现的特征

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

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

另见:

【讨论】:

  • 链接+1。不过,我不太明白第三句话与性能有什么关系。
  • 来自here(似乎可信):'John [Resig] 没有提到的是严格模式可能会带来更好的性能。如果浏览器被告知“我声明这段代码是好的和正确的”,它可以花更少的时间来处理歧义,并着手处理手头的业务。'
  • @sje397:strict 模式的另一个好处是,如果一个函数声明了一个局部变量 foo 并且没有定义任何捕获它的嵌套函数,它会存储在第一次读取之前将数字存入foo,并且永远不会将除数字之外的任何内容存储到foo,那么被调用的函数(或其他任何内容)不可能导致foo 保存除数字之外的任何内容.很容易确定上述条件是否成立,并且使用数字可以比使用碰巧是数字的多态对象快得多。
【解决方案3】:

根据这个测试,“严格模式”可以快 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


有趣的是,在“严格模式”下,参数数组的操作可以快 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

【讨论】:

  • 在我的 Chrome 浏览器上,2017 年的今天,在你的基准测试中,非严格版本分别比严格版本慢 15% 和 70%。我想这意味着性能差异比以前小了,但仍然相当显着。知道是什么导致了这些性能差异吗?
【解决方案4】:

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

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

有两点需要注意:

  1. ECMAScript 3 中不存在对严格模式的检查。虽然它相对轻量级,但与它们的 ECMAScript 3 对应物相比,符合标准的 JavaScript 实现现在至少运行了一项额外的条件检查。是的...我知道像这样的单次检查会消耗很少的时钟周期,但小事加起来
  2. 因为严格模式主要是 JavaScript 的解析时间功能,所以当为某些网站(例如 SunSpider)启用严格模式时,您最喜欢的浏览器不会显示出太多性能下降。也就是说,性能下降发生在代码执行之前,这意味着它可以被最终用户感知,但在很大程度上无法使用 Date 对象来衡量测量块执行时间

【讨论】:

  • 但是你怎么知道的,例如v8 没有利用严格模式进行额外优化?
  • 我曾在 Internet Explorer 10 的严格模式下进行性能测试。我能给你的最好的例子是,如果你有两个相同的大 JavaScript 文件,没有违反严格模式并且其中只有一个包含“use strict”,没有它的那个会运行得更快,因为它不是运行严格模式检查。仅仅因为您在严格模式下删除了对“with”的支持,并不意味着您可以直接从解析器中删除它(在非严格模式下仍然必须允许它)。不,相反,您的 DLL 大小实际上已经增加,因为您的执行时间也是如此。
猜你喜欢
  • 1970-01-01
  • 2021-03-28
  • 2015-12-10
  • 1970-01-01
  • 2020-11-07
  • 2014-07-09
  • 1970-01-01
相关资源
最近更新 更多