Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 慢缓冲区_Node.js_Performance_Buffer - Fatal编程技术网

Node.js 慢缓冲区

Node.js 慢缓冲区,node.js,performance,buffer,Node.js,Performance,Buffer,当我以64Kb的大小读取一个16MB的文件,并对每个文件执行Buffer.concat操作时,后者的速度非常慢,需要花费整整4秒的时间 在Node.js中连接缓冲区有更好的方法吗 使用的Node.js版本:7.10.0,在Windows 10下(均为64位) 这个问题是在研究以下问题时提出的:,它影响了大量的受众 PostgreSQL驱动程序以64Kb的块读取大的bytea列,然后将它们连接起来。我们发现调用Buffer.concat是此类示例中性能巨大损失的罪魁祸首。与其每次连接(每次都会创

当我以64Kb的大小读取一个16MB的文件,并对每个文件执行
Buffer.concat
操作时,后者的速度非常慢,需要花费整整4秒的时间

在Node.js中连接缓冲区有更好的方法吗

使用的Node.js版本:7.10.0,在Windows 10下(均为64位)


这个问题是在研究以下问题时提出的:,它影响了大量的受众


PostgreSQL驱动程序以64Kb的块读取大的
bytea
列,然后将它们连接起来。我们发现调用
Buffer.concat
是此类示例中性能巨大损失的罪魁祸首。

与其每次连接(每次都会创建一个新的缓冲区),不如在最后保留一个包含所有缓冲区和concat的数组


Buffer.concat()
可以获取整个缓冲区列表。然后在一次操作中完成

如果您从文件中读取数据并知道该文件的大小,则可以预先分配最终缓冲区。然后,每次您获得一块数据时,您只需将其写入16Mb的大缓冲区即可

// use the "unsafe" version to avoid clearing 16Mb for nothing
let buf = Buffer.allocUnsafe(file_size)

let pos = 0
file.on('data', (chunk) => {
    buf.fill(chunk, pos, pos + chunk.length)
    pos += chunk.length
})

if(pos != file_size) throw new Error('Ooops! something went wrong.')
@Brad的代码示例的主要区别在于,您将使用一个块的16Mb+大小(大致),而不是一个块的32Mb+大小

此外,每个区块都有一个标头、各种指针等,所以您不太可能使用33Mb甚至34Mb。。。那是更多的内存。复制的RAM量在其他方面是相同的。也就是说,可能是节点在复制时开始读取下一个块,以便使其透明。当在
'end'
事件中的一大块中完成时,您将不得不等待
contact()
完成,而不并行执行任何其他操作



如果您正在接收HTTP
POST
并正在阅读它。请记住,您会得到一个
内容长度
参数,因此在这种情况下,您也有长度,并且可以在读取数据之前预先分配整个缓冲区。

为什么必须以64KB的片段读取数据?在任何一种情况下,都不应该花费4秒钟的时间。你能把这段代码的范围缩小吗?@Brad我刚刚添加了一个解释。将每段代码放入一个数组中,并在整个过程中使用
Buffer.concat()
。O(n)而不是O(n²)复制时间。只有在读取数据之前预先写入所有数据时,此策略才有效。如果您在写入流时从流中读取数据,那么您要么需要一种从缓冲区数组中提取正确数据的策略(这可能会变得混乱),要么需要以一种性能良好的方式增长缓冲区(传统解决方案)。本文对缓冲区加倍有一个解释:@MatthewAmato您可以随时从缓冲区数组中读取数据。由于缓冲区的大小在长度上是一致的,所以如果您真的需要在完成之前读取数据块,那么提取所需的数据块实际上是很简单的。考虑到这个问题是关于连接整个16MB块的,看来他们无论如何都要等到所有的块都出现了,只是要小心盲目地信任HTTP客户端的
Content Length
。它们可能会给你带来巨大的价值,并立即使你的服务器崩溃。或者,
内容长度
实际上不必精确。这是一个非常常见的漏洞。我首先测试最大大小,如果超出限制,则立即抛出,并在上载完成后验证收到的内容与
内容长度
中指定的内容。如果错了,我再扔一次。最后,我验证接收到的数据是否存在污染数据。所以我应该承担该领域99%的潜在问题。。。