Eigentlich wollte ich den heutigen Artikel neuen JavaScript Array-Features widmen, die am kommen oder schon da sind (forEach(), indexOf(), Iteratoren, Generatoren, etc.). Garnieren wollte ich das ganze mit ein paar Benchmarks, um bestenfalls zu zeigen dass die ‘nativen’ Arraymethoden der Browser meine selbstgeschriebenen Equivalente vor Neid erblassen lassen und was die Zukunft bringt. Doch das wäre wohl zu einfach gewesen…
Das Ergebnis war überraschend: Während meine Benchmarks im v8 (d.h. die JS-Engine von Chrome) zwar zeigten, dass manche meiner Methoden nur einen kleinen Tick langsamer waren (manche aber auch schneller), war es bei Spidermonkey (die Firefox engine) genau umgekehrt: Sobald dort die Tracing Engine aktiviert war (was Standard seit FF > 3.5 ist), lief mein eigener Code mit einer viel besseren Performance (z.T um den Faktor x6) als die ‘nativen’ SpiderMonkey-Methoden, die in C++ geschrieben waren.

Was komisch klingt liegt an der Art und Weise wie Fuchs optimiert: Mein eigener Code wird zur Laufzeit ge’traced’ (grob gesagt: Es wird verfolgt, ob die Typen der Variablen gleichbleibend sind und dementsprechend wenn möglich auf Typkonvertierungen und -überprüfungen verzichtet – wer Details will findet eine gute Einführung im Mozilla Blog ). Dementsprechend werden bei meinem selbstgeschriebenen Code weniger Operationen pro Durchgang benötigt. Bei den nativen Methoden ist dass anscheinend anders: Eine kleine Wanderung in den C++ Code von Spidermonkey zeigte, dass z.B. die Array.prototype.every() Methode Typen immer überprüft und konvertiert und ich schätze, dass hier derzeit kein Tracing stattfindet.
Die größten Performancesprünge lagen dabei interessanterweise bei Methoden, die Funktionen als Argumente nehmen, wie z.b. Array.map(), Array.filter(), Array.forEach().
Hier noch mein Benchmark zum selber Ausprobieren. Natürlich ist das immer ein Szenario und deckt damit nicht jeden Fall ab – ein anderer Benchmark kann ein völlig anderes Ergebnis liefern, ein neuerer Browser andere Werte, etc. Ich habe die Funktionen was Argumente und Verhalten angeht nachgeschrieben, allerdings ist ein 1:1 Vergleich immer schwer und das Szenario (wie bei einem Benchmark üblich) natürlich extrem (10000 Elemente im Array und 1000 Durchgänge).
Das eigentliche Fazit: Gerade bei neuen Methoden wie den JavaScript 1.6+ Array Funktionen, die nicht bei jedem Browser vorhanden sind sollte immer erst geprüft ob sich der Aufwand lohnt, oder ob man auf ‘konservative’ Methoden zurückgreift. Cross-Browser-Kompatibilität erfordert immer Mehraufwand, und dieser wird nur gerechtfertigt wenn unterm Strich ein Mehrwert herauskommt. Und darauf will ich hinaus: Wir Webentwickler werden zwar einige neue Features wie Iteratoren und Generatoren bekommen (Firefox unterstützt diese auch schon bereits) – trotzdem ergibt es oft Sinn, lieber auf Helferfunktionen von Core-Toolset wie Prototype, JQuery oder ExtJS zu setzen, die browserübergreifend die selben Funktionalitäten anbieten. Die ‘neueren’ Methoden sind  a) nicht in jedem Browser vorhanden, und b) evtl. sogar langsamer, oder nur minimal schneller – womit sie derzeit für den Produktiveinsatz ausscheiden.
Ich will hier natürlich keinen Fortschritt aufhalten: Es ist gut, dass sinnvolle Hilfsmethoden wie filter() oder map() Einzug in den Standard finden und ich werde sie sicher auch selbst nutzen wenn Sie verbreitet genug sind. Allerdings sollte man für den Produktiveinsatz eher mit geschärften Bewusstsein an neue (Sprach-)Features wagen.