2017-05-10 2 views
1

Wenn ich eine 16MB-Datei in Stücken von 64KB lese, und mache Buffer.concat auf jedem Stück, letzteres erweist sich als unglaublich langsam, dauert eine ganze 4s, um durch die Menge zu gehen.Slow Buffer.concat

Gibt es eine bessere Möglichkeit, einen Puffer in Node.js zu verketten?

Node.js Version verwendet: 7.10.0, unter Windows 10 (beide sind 64-Bit).


Diese Frage gestellt wird, während das folgende Problem untersucht: https://github.com/brianc/node-postgres/issues/1286, die ein großes Publikum beeinflusst.

Der PostgreSQL-Treiber liest große bytea Spalten in Blöcken von 64 KB und verkettet sie dann. Wir fanden heraus, dass der Anruf Buffer.concat der Schuldige hinter einem riesigen Leistungsverlust in solchen Beispielen ist.

+0

Warum müssen Sie in 64KB Stücken lesen? In jedem Fall sollte das nicht 4 Sekunden dauern. Können Sie diesen Code eingrenzen? – Brad

+0

@Brad Ich habe gerade eine Erklärung hinzugefügt. –

+2

Schieben Sie jedes Stück in ein Array und verwenden Sie 'Buffer.concat()' auf das Ganze zusammen. O (n) statt O (n²) Zeit zu kopieren. – Ryan

Antwort

1

Anstatt jedes Mal zu verketten (was jedes Mal einen neuen Puffer erzeugt), behalten Sie einfach ein Array aller Ihrer Puffer und concat am Ende.

Buffer.concat() kann eine ganze Liste von Puffern nehmen. Dann ist es in einer Operation erledigt. https://nodejs.org/api/buffer.html#buffer_class_method_buffer_concat_list_totallength

+0

Diese Strategie funktioniert nur, wenn Sie alle Ihre Daten im Voraus schreiben, bevor Sie sie lesen. Wenn Sie während des Schreibens aus dem Stream lesen, benötigen Sie entweder eine Strategie, um die richtigen Daten aus dem Puffer-Array herauszuholen (was unübersichtlich werden kann), oder Sie müssen den Puffer leistungsfähig erweitern (traditionelle Lösung)). Dieser Artikel hat eine Erklärung der Pufferverdoppelung: https://crntaylor.wordpress.com/2011/07/15/optimal-memory-reallocation-and-the-golden-ratio/ –

+0

@MatthewAmato Sie können von Ihrem Array von Puffern lesen jederzeit. Da die Größe der Puffer in der Länge gleich ist, ist es eigentlich trivial, herauszubekommen, welches Stück benötigt wird, falls Sie tatsächlich von diesem lesen müssen, bevor es fertig ist. Da die Frage nach der Verkettung eines ganzen 16-MB-Chunks besteht, scheint es so zu sein, dass man warten muss, bis alle Teile vorhanden sind. – Brad