2016-09-01 3 views
1

Ich habe 100 CSV-Dateien, jede etwa 50.000.000 Zeilen und jeweils 3 Zellen.Schleife über binäre Float64Array-Datei - NodeJS

Jede Zeile muss ein Ereignis auslösen, um einige Berechnungen durchzuführen. Mit der npm read-line lib, die die CSV über eine Pipe liest, könnte ich pro Sekunde etwa 1.000.000 Zyklen dieses Prozesses bekommen (1 Knoten-Thread).

Aber dieser Prozess hat eine Menge von Schritten, nur ein paar Zahlen zu erhalten

  1. öffnen CSV-Datei-Stream
  2. Stringify jeder Chunk
  3. Suche nach neuen Zeile \ n in Chunk
  4. Split daß die Leitung in eine Anordnung (3 Zellen)
  5. parseFloat jede Zelle

Um sie noch schneller analysieren zu können, könnte ich die csv-Datei in eine Binärdatei konvertieren. Also habe ich eine binäre Float64Array-Pufferdatei erstellt, da alle Werte in den Zellen fließende Zahlen sind.

let counter = 0 ;; 
rows.forEach(function (row) { 

    row.forEach(function(cell) { 

     buffer.writeDoubleLE(cell, counter++ * Float64Array.BYTES_PER_ELEMENT); 
    }) 
}); 
writeStream.write(buffer) 
writeStream.end() 

Dann hat es nur, dies zu tun Schritte

  1. öffnen .bin-Datei-Stream
  2. Konvertieren jeder Strompuffer Brocken (Brocken = 3-Zellen) zu Arraybuffer Array64Float

    fs.createReadStream(fileName, {highWaterMark: 24}) 
        //.pause() 
        .on('data', chunk => { 
         //this._stream.pause(); 
    
         this._bufferOffset = 0; 
    
         this.emit('tick', new Float64Array(chunk.buffer, chunk.byteOffset, chunk.byteLength/Float64Array.BYTES_PER_ELEMENT)); 
        }) 
        .on('close',() => { 
         let nextFile = this._getNextBINFilePath(); 
    
         if (!nextFile) { 
          return this.emit('end'); 
         } 
    
         this._initTestStream(); 
        }) 
    

Alles gut so weit. Ich kann die Binärdatei lesen und den Inhalt Zeile für Zeile in einem Float64Array analysieren.

Aber aus irgendeinem Grund scheint es langsamer als das Lesen einer CSV (Text) -Datei, teilen Sie es durch die Zeile, teilen Sie es durch Komma, parseFloat über die Zellen.

Sehe ich nicht das größere Bild von Binär, Puffer und TypedArrays?

Dank

Antwort

1

Ich denke, die Engpass new Float64Array für jeden (kleinen) Brocken ist.

Sie könnten stattdessen 3 Float64-Parameter verwenden oder direkt am Chunk arbeiten.

Oder verwenden Sie Float64Array auf einem viel größeren Chunk, und rufen Sie die Funktion wiederholt mit derselben Float64Array.

+0

In der Tat. Ich erhöhte die Chunk-Größe, machte einen Puffer dafür und es ging schon viel besser. Ziemlich blöd, denn ich las 24 Bytes gleichzeitig, rief einen Float64Array-Konstruktor mit der gesamten Hintergrundverarbeitung auf und erwartete ein gutes Ergebnis. 750.000 pro Sekunde waren immer noch schnell, wenn man daran denkt. Jetzt werden fast 10.000.000 erreicht p/s :) Danke – DutchKevv