JavaScript Engines: Performance-Steigerung der Browser

JavaScript gilt unter Nutzern anderer Sprachen oft als langsam: Dabei hat die mangelnde Performance historische Gründe, die die Browser-Engines heutzutage ausgleichen können.

In Pocket speichern vorlesen Druckansicht 271 Kommentare lesen
JavaScript Engines: Performance-Steigerung der Browser
Lesezeit: 17 Min.
Von
  • Rainer Hahnekamp
Inhaltsverzeichnis

Anwender von Sprachen wie Java oder C# belächeln JavaScript nach wie vor. Es sei wegen des schlechten Sprachdesigns sowie der mangelnden Performance keine "vollwertige" Sprache. Das war vielleicht vor 15 Jahren der Fall: Inzwischen hat sich JavaScript an allen Fronten kontinuierlich verbessert. Jährlich erscheint ein neuer und verbesserter Standard – bezüglich Performance braucht sich JavaScript ebenfalls nicht mehr zu verstecken. Für die Ausführungsgeschwindigkeit ist die Engine verantwortlich, die den Code ausführt. Federführend ist bei JavaScript Google mit der Engine V8 zu nennen.

Getreu dem Motto "Um die Gegenwart zu verstehen, muss man die Vergangenheit kennen" hier nun ein Blick in die Vergangenheit von JavaScript.

(() => {
const han = {firstname: "Han", lastname: "Solo"};
const luke = {firstname: "Luke", lastname: "Skywalker"};
const leia = {firstname: "Leia", lastname: "Organa"};
const obi = {firstname: "Obi-Wan", lastname: "Kenobi"};
const yoda = {firstname: "", lastname: "Yoda"};
const people = [
han, luke, leia, obi,
yoda, luke, leia, obi
];

const getName = (person) => person.lastname;

console.time("engine");
for(var i = 0; i < 1000 * 1000 * 1000; i++) {
getName(people[i & 7]);
}
console.timeEnd("engine");
})();

1,328 Sekunden (Dell XPS 15 (9570) mit i7-8750H, Windows 10 Pro, Chrome 71)

Das Beispiel ist relativ simpel. Es legt fünf Objekte an, die Figuren aus den Star-Wars-Filmen mit Vor- und Nachnamen repräsentieren. Danach laufen sie in einer Schleife 1.000.000.000 durch eine Funktion, die den Nachnamen zurückgibt. Je nach Geschwindigkeit des Rechners dauert die Ausführung bis zu zwei Sekunden. Das ändert sich jedoch schlagartig, wenn jedes Objekt eine weitere Property erhält beziehungsweise im Fall von "Yoda" eine wegfällt:

(() => {
const han = {firstname: "Han", lastname: "Solo", spacecraft: "Falcon"};
const luke = {firstname: "Luke", lastname: "Skywalker", job: "Jedi"};
const leia = {firstname: "Leia", lastname: "Organa", gender: "female"};
const obi = {firstname: "Obi-Wan", lastname: "Kenobi", retired: true};
const yoda = {lastname: "Yoda"};

const people = [
han, luke, leia, obi,
yoda, luke, leia, obi];

const getName = (person) => person.lastname;

console.time("engine");
for(var i = 0; i < 1000 * 1000 * 1000; i++) {
getName(people[i & 7]);
}
console.timeEnd("engine");
})();

11,386 Sekunden (Dell XPS 15 (9570) mit i7-8750H, Windows 10 Pro, Chrome 71)

Das Beispiel ist speziell auf Chrome zugeschnitten und ist kein Benchmark. Es ist relativ unwahrscheinlich, dass derartiger Code in einer praktischen Anwendung vorkommt. Nichtsdestoweniger eignet es sich perfekt, um die inneren Vorgänge einer Engine zu veranschaulichen.