我有100个CSV文件,每个文件大约有50.000.000行,每行包含3个单元格。
每行需要触发一个事件来进行一些计算。 使用npm读取行lib,通过管道读取CSV,我每秒可以获得大约1.000.000个周期的进程(1个节点线程)。
但是这个过程做了很多步骤,只是为了得到一些数字
因此要更快地解析它们,我将csv文件转换为二进制文件可能有所帮助。所以我创建了一个二进制Float64Array缓冲区文件,因为单元格中的所有值都是浮点数。
let counter = 0 ;;
rows.forEach(function (row) {
row.forEach(function(cell) {
buffer.writeDoubleLE(cell, counter++ * Float64Array.BYTES_PER_ELEMENT);
})
});
writeStream.write(buffer)
writeStream.end()
然后它只需执行此步骤
将每个流缓冲区块(chunk = 3个单元格)转换为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();
})
到目前为止一切顺利。我可以读取二进制文件并在Float64Array中逐行解析其内容。
但由于某些原因,它似乎比读取csv(文本)文件慢,按行拆分,用逗号分隔,对单元格进行parseFloat。
我没有看到二进制,缓冲区和TypedArrays的大局?
由于
答案 0 :(得分:1)
我认为每个(小)块的瓶颈都是new Float64Array
。
您可以使用3个Float64参数,或直接在块上工作。
或者在更大的块上使用Float64Array
,并使用相同的Float64Array
重复调用该函数。