我正在用vmware下的ssd上的节点复制文件,但是性能非常低。我用来测量实际速度的基准如下:

$ hdparm -tT /dev/sda

/dev/sda:
 Timing cached reads:   12004 MB in  1.99 seconds = 6025.64 MB/sec
 Timing buffered disk reads: 1370 MB in  3.00 seconds = 456.29 MB/sec

但是,以下复制文件的节点代码非常慢,EVNE TEH后续运行不会使其更快:
var fs  = require("fs");
fs.createReadStream("bigfile").pipe(fs.createWriteStream("tempbigfile"));

运行方式:
$ seq 1 10000000 > bigfile
$ ll bigfile -h
-rw-rw-r-- 1 mustafa mustafa 848M Jun  3 03:30 bigfile
$ time node test.js

real    0m4.973s
user    0m2.621s
sys     0m7.236s
$ time node test.js

real    0m5.370s
user    0m2.496s
sys     0m7.190s

这里的问题是什么?我怎样才能加快速度?我相信只要调整缓冲区的大小,就可以用C语言更快地写它。让我困惑的是,当我编写简单的几乎是pv等价的程序时,它将stdin连接到stdout,如下所示,速度非常快。
process.stdin.pipe(process.stdout);

运行方式:
$ dd if=/dev/zero bs=8M count=128 | pv | dd of=/dev/null
128+0 records in 174MB/s] [        <=>                                                                                ]
128+0 records out
1073741824 bytes (1.1 GB) copied, 5.78077 s, 186 MB/s
   1GB 0:00:05 [ 177MB/s] [          <=>                                                                              ]
2097152+0 records in
2097152+0 records out
1073741824 bytes (1.1 GB) copied, 5.78131 s, 186 MB/s
$ dd if=/dev/zero bs=8M count=128 |  dd of=/dev/null
128+0 records in
128+0 records out
1073741824 bytes (1.1 GB) copied, 5.57005 s, 193 MB/s
2097152+0 records in
2097152+0 records out
1073741824 bytes (1.1 GB) copied, 5.5704 s, 193 MB/s
$ dd if=/dev/zero bs=8M count=128 | node test.js | dd of=/dev/null
128+0 records in
128+0 records out
1073741824 bytes (1.1 GB) copied, 4.61734 s, 233 MB/s
2097152+0 records in
2097152+0 records out
1073741824 bytes (1.1 GB) copied, 4.62766 s, 232 MB/s
$ dd if=/dev/zero bs=8M count=128 | node test.js | dd of=/dev/null
128+0 records in
128+0 records out
1073741824 bytes (1.1 GB) copied, 4.22107 s, 254 MB/s
2097152+0 records in
2097152+0 records out
1073741824 bytes (1.1 GB) copied, 4.23231 s, 254 MB/s
$ dd if=/dev/zero bs=8M count=128 | dd of=/dev/null
128+0 records in
128+0 records out
1073741824 bytes (1.1 GB) copied, 5.70124 s, 188 MB/s
2097152+0 records in
2097152+0 records out
1073741824 bytes (1.1 GB) copied, 5.70144 s, 188 MB/s
$ dd if=/dev/zero bs=8M count=128 | node test.js | dd of=/dev/null
128+0 records in
128+0 records out
1073741824 bytes (1.1 GB) copied, 4.51055 s, 238 MB/s
2097152+0 records in
2097152+0 records out
1073741824 bytes (1.1 GB) copied, 4.52087 s, 238 MB/s

最佳答案

我不知道你问题的答案,但也许这有助于你调查这个问题。
在node.js关于流缓冲的文档中,它说:
流将在内部存储数据
可以使用writable.writableBuffer
分别为。
可能缓冲的数据量取决于
选项传递到流的构造函数中。对于正常流,
readable.readableBuffer选项指定字节总数。对于溪流
在对象模式下操作时,highWaterMark指定一个总数
对象数量….
highWaterMarkapi的一个关键目标,尤其是Writable方法,
将数据缓冲限制在可接受的水平,以便
不同速度的来源和目的地不会压倒
可用内存。
资料来源:Readable
因此,您可以使用缓冲区大小来提高速度:

var fs = require('fs');
var path = require('path');
var from = path.normalize(process.argv[2]);
var to = path.normalize(process.argv[3]);

var readOpts = {highWaterMark: Math.pow(2,16)};  // 65536
var writeOpts = {highWaterMark: Math.pow(2,16)}; // 65536

var source = fs.createReadStream(from, readOpts);
var destiny = fs.createWriteStream(to, writeOpts)

source.pipe(destiny);

stream.pipe()
http://www.nodejs.org/api/stream.html#stream_buffering
https://nodejs.org/api/stream.html#stream_writable_writablehighwatermark

07-28 02:03
查看更多