Ist der strenge Modus performanter?

74

Ist die Ausführung von Javascript in einem Browser im "strengen Modus" im Allgemeinen leistungsfähiger? Führt einer der wichtigsten Browser zusätzliche Optimierungen durch oder verwendet er andere Techniken, die die Leistung im strengen Modus verbessern?

Ist der strikte Modus neben seinen anderen Zielen dazu gedacht, Browsern die Möglichkeit zu geben, zusätzliche Optimierungen oder andere Leistungsverbesserungen einzuführen?

sje397
quelle
Welche Browser unterstützen ECMAScript 5 jetzt überhaupt?
Jamie Wong
3
@ Jamie kieax.github.com/es5-compat-table
Matthew J Morrison
@ Jamie Wong - siehe stackoverflow.com/questions/2280115/…
sje397
3
@ Matthew: schöner Link! @ sje397: Die einzige vollständige ECMAScript 5-Implementierung in dieser Liste ist BESEN (auch noch nie davon gehört). Auf der Homepage wird Folgendes vermerkt: "Strenger Code wird schneller ausgeführt als nicht strenger Code. Verwenden Sie aus diesem Grund vorzugsweise" use strict ", wobei ist es möglich "
Crescent Fresh
2
IIRC Douglas Crockfords Behauptungen irgendwo in diesem Vortrag, dass das withSchlüsselwort nicht nur eine schlechte Leistung erbringt, sondern es nur in der Sprache hat, verlangsamt die gesamte Sprache. Dieser Link aus der Antwort von CMS besagt, dass das withSchlüsselwort im strengen Modus nicht funktioniert. Dies scheint zumindest auf das Potenzial für eine gewisse Beschleunigung hinzuweisen .
MatrixFrog

Antworten:

25

Ist der strikte Modus unter anderem dazu gedacht, dass Browser zusätzliche Optimierungen oder andere Leistungsverbesserungen einführen können?

Ob dies beabsichtigt war oder nicht , bin ich mir nicht sicher, obwohl ich denke, dass die Antwort ja ist.

Ich kann jedoch mit Sicherheit sagen, dass der strikte Modus diese Möglichkeiten bietet und die Browser sie implementieren werden - unabhängig davon, ob die Bereitstellung dieser Möglichkeiten ein beabsichtigtes Ziel für das ECMA-Komitee war. Ich würde jedoch nicht erwarten, dass all diese Gelegenheiten sofort genutzt werden. In vielen Fällen ist es wahrscheinlich, dass das Mantra zuerst die Korrektheit und später die Leistung ist, da der strenge Modus derzeit nicht weit verbreitet ist. (Ich arbeite an der JavaScript-Engine von Mozilla und habe verschiedene Teile des strengen Modus implementiert. Wir implementieren sie in der Regel auf diese Weise - obwohl ich mir wahrscheinlich ein oder zwei Ausnahmen vorstellen könnte, wenn ich es versuchen würde.)

Jeff Walden
quelle
4
Ja, das Designziel des strengen Modus bestand darin, das lexikalische Scoping zu ermöglichen (aus diesem Grund sind Dinge wie mit deaktiviert). Es war die Absicht vom ersten Tag an.
Benjamin Gruenbaum
22

Im strengen Modus geht es nicht wirklich um Leistung, sondern um eine strenge Variante der Sprache. Das Hauptziel besteht darin, Fehler zu vermeiden, die als fehleranfällig gelten .

Grundsätzlich ist es das Ziel, die Sprache sicherer zu machen , viele semantische Änderungen einzuführen, außerdem werden zusätzliche Fehlerprüfungen durchgeführt und Fehler sind verrauscht, in nicht-strengem Code scheitern Dinge nur stillschweigend.

In Bezug auf die Leistung fällt es Browser-Anbietern derzeit schwer, den strengen Modus zu implementieren. Das Problem besteht darin, dass die JS-Engines hauptsächlich auf ECMAScript 3 basieren und die Implementierung des strengen Modus nicht einfach ist, da der Umfang der Strenge sehr flexibel ist. Sie können nicht strengen und strengen Code mischen.

Siehe auch:

Christian C. Salvadó
quelle
+1 für die Links. Ich verstehe nicht ganz, wie dieser dritte Satz etwas mit der Leistung zu tun hat.
sje397
4
von hier aus (scheint glaubwürdig): 'Was John [Resig] nicht erwähnt, ist, dass der strenge Modus wahrscheinlich zu einer höheren Leistung führen wird. Wenn dem Browser die Meldung "Ich erkläre diesen Code als gut und richtig" mitgeteilt wird, kann er weniger Zeit mit dem Umgang mit Unklarheiten verbringen und sich an das jeweilige Unternehmen wenden. "
sje397
@ sje397: Ein weiterer Vorteil des strictModus ist , dass , wenn eine Funktion eine lokale Variable deklariert foound nicht nicht definiert alle verschachtelten Funktionen , die Erfassung es, es eine Zahl in speichert , foobevor das erste Mal las es und nie speichert etwas anderes als eine Zahl in foo, dann Eine aufgerufene Funktion (oder etwas anderes) kann fooauf keinen Fall dazu führen , dass etwas anderes als eine Zahl gespeichert wird. Es ist ziemlich einfach festzustellen, dass die oben genannten Bedingungen gelten, und das Arbeiten mit Zahlen kann viel schneller erfolgen als das Arbeiten mit polymorphen Objekten, bei denen es sich zufällig um Zahlen handelt.
Supercat
14

Gemäß diesem Test „Strict - Modus“ kann etwa 25% schneller sein.

<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>

Dies kann hier getestet werden: http://jsperf.com/strict-mode


Interessanterweise kann die Manipulation des Argumentarrays im "strengen Modus" etwa sechsmal schneller sein!

<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>

Hier ist der jsPerf-Test: http://jsperf.com/strict-mode-arguments

unerschrocken
quelle
2
In meinem Chrome-Browser ist die nicht strenge Version heute im Jahr 2017 etwa 15% bzw. 70% langsamer als die strenge Version in Ihren Benchmarks. Ich denke, das bedeutet, dass der Leistungsunterschied kleiner ist als früher, aber immer noch ziemlich signifikant. Irgendeine Idee, was diese Leistungsunterschiede verursacht?
John Slegers
4

Zum größten Teil nein . Wenn Sie das ECMAScript 5-Standarddokument genau untersuchen, werden Sie feststellen, dass so gut wie alle Vorkommen des Strict Mode in den Pseudocode-Algorithmen Folgendes betragen:

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

Hierbei sind zwei Dinge zu beachten:

  1. Die Überprüfungen des strengen Modus waren in ECMAScript 3 nicht vorhanden. Obwohl es relativ leicht ist, führen konforme Implementierungen von JavaScript jetzt mindestens eine zusätzliche bedingte Überprüfung im Vergleich zu ihren ECMAScript 3-Gegenstücken aus. Ja ... ich weiß, dass ein einziger Scheck wie dieser nur sehr wenige Taktzyklen brennt, aber kleine Dinge summieren sich
  2. Da der strenge Modus in erster Linie eine Analysezeitfunktion von JavaScript ist, zeigt Ihr Lieblingsbrowser keinen großen Leistungsabfall, wenn der strenge Modus für eine Website (z. B. SunSpider) aktiviert ist. Das heißt, die Leistungsverschlechterung tritt auf, bevor Code ausgeführt wird, was bedeutet, dass er für Endbenutzer wahrnehmbar sein könnte , aber mit dem Date- Objekt zum Messen der Blockausführungszeit weitgehend unermesslich ist
Dave
quelle
2
Aber woher wissen Sie, dass z. B. v8 den strengen Modus nicht für zusätzliche Optimierungen nutzt?
UpTheCreek
6
Ich habe unter anderem am Strict Mode für Internet Explorer 10 auf Leistungstests gearbeitet. Das beste Beispiel, das ich Ihnen geben kann, ist, dass wenn Sie zwei identische große JavaScript-Dateien ohne strikte Modusverletzungen haben und nur eine von ihnen "use strict" enthält, die ohne schneller ausgeführt wird, da die strengen Modusprüfungen nicht ausgeführt werden. Nur weil Sie die Unterstützung für 'with' im strikten Modus entfernen, heißt das nicht, dass Sie sie sofort aus Ihrem Parser entfernen können (was es immer noch in nicht striktem Modus zulassen muss). Nein, stattdessen hat sich Ihre DLL-Größe und Ihre Ausführungszeit tatsächlich erhöht .
Dave