Seite wählen

Low-level memory access in JavaScript: Typed arrays.

von | Sep 22, 2011 | Development

Interessante, aber eher unbekannte (da sehr neue) Datentypen in JavaScript  sind der ArrayBuffer und Typed Arrays. Diese Datentypen wurden in erster Linie eingeführt um effektiv auf Binärdaten zugreifen zu können.
Grundlage für alles ist der ArrayBuffer, ein einfacher Datentyp, den man beim Erstellen mitteilt wie viele Bytes er belegen soll. Das besondere ist dass dieser ArrayBuffer an sich keine Möglichkeit besitzt gelesen oder beschrieben zu werden (auch wenn die Spezifikation einen Proposal für eine ’splice‘ Methode hat). Hier kommen die Typed Array Datentypen (oder wie in der Spec: Views) hinzu. Diese ermöglichen es dem Speicher eine logische Aufteilung zu geben, z.B. als ein Array von 32-Bit großen Floats im Falle von Float32Array:
var buffer = new ArrayBuffer(8); // 8 Byte im speicher reservieren
var floatBuffer = new Float32Array(buffer); //floatBuffer ist jetzt ein Array mit 2 elementen (8*8/32 = 2)
floatBuffer[0] = 0.255315; // ab hier gibt es kaum einen Unterschied zu einem normalen js array, ausser dass indexüberlaufe einfach ignoriert werden
floatBuffer[1] = 0.3535;

Der Nutzen ist, dass man mit JavaScript nun effektiv mit binären Daten arbeiten kann. Davor musste man Binärdaten als String darstellen, mit charCodeAt Byteweise auslesen und Datentypen wie Floats und Integers ebenfalls aus Byteblöcken zusammenbauen.
Mich hat allerdings eher interessiert, wie sich die Performance von ’normalen‘ Operationen auf Arrays verhält, wenn man das JavaScript Array Objekt mit dem ArrayBuffer austauscht. Mein Benchmark dafür ist sehr einfach:

for(var i=0;i<size;i++) {
    container[i] = Math.random();
}
var sum = 0;
for(var i=1;i<size;i++) {
sum += container[i];
}
var avg = sum/size;

Ich fülle hier einfach ein Array ‚container‘ (welches wahlweise ein ArrayBuffer oder ein Array Objekt ist) mit Zufallswerten und berechne anschliessend den Durchschnitt. Das ganze habe ich auf meinem MacBook Pro 13″ (i5 2,3Ghz) mit ’size‘ von 21 bis 225 einmal im Chrome 14 getestet und einmal im Firefox 6. Die Ergebnisse in bunt (Die Elemente mit 0 ms habe ich mal herausgelassen):

Man sieht ganz klar, wie die Performance des internen Arrays ab ca. 65536 Elementen ausreisst (vor allem im Chrome), während das Float32Array recht linear skaliert. Bei sehr großen Datenmengen lohnt es sich also, mal ein Float32Array -wenn vorhanden- auszuprobieren. Einen Nachteil haben die BufferArray Objekte allerdings: Das erstellen ist aufwändiger als bei internen Arrays. Generell sollte man immer die Performance messen und schauen, ob man wirklich einen sinnvollen Geschwindigkeitsbonus durch Typed Arrays bekommt – mein Benchmark hat keinen Anspruch auf Allgemeingültigkeit.
Fazit: JavaScript kann jetzt endlich effektiv mit größeren und binären Datenmengen umgehen. Man muss zwar entscheiden, ob sich der Aufwand lohnt – immerhin muss man, will man kompatibel zu älteren Browsern bleiben, eine Fallback-Variante anbieten. In Kombination mit WebSockets und der File Api eröffnen sich aber ganz neue Möglichkeiten (wie z.B. pdf.js, das PDF direkt in JavaScript rendert).

0 Kommentare

Trackbacks/Pingbacks

  1. Weekly Snap: CPU Limit, MOTP, Typed Arrays & Training Courses in 2012 « NETWAYS Blog - [...] the development team, Jannis then had a look at low-level memory access in java script with typed arrays. The…

Einen Kommentar abschicken

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Mehr Beiträge zum Thema Development

Mein PHP-Trainingsprojekt

PHP Schulung Vor kurzem haben wir begonnen, eine neue Programmiersprache zu lernen – PHP. In der ersten Woche haben wir mit den Grundlagen wie Variablen, Arrays, Schleifen begonnen und uns schrittweise zu komplizierterer Syntax wie Funktionen, Objekten und Klassen...

check_prometheus ist jetzt öffentlich verfügbar!

Monitoring ist komplex, das wissen wir hier bei NETWAYS leider zu gut. Deswegen laufen in der Infrastruktur auch mal gerne mehrere Tools für die Überwachung. Zwei gern gesehene Kandidaten sind dabei Icinga und Prometheus. Icinga und Prometheus erfüllen...