Skip to content

Commit 3c2e4ad

Browse files
committed
fs: improve writevSync performance
1 parent 4b35a9c commit 3c2e4ad

File tree

3 files changed

+67
-14
lines changed

3 files changed

+67
-14
lines changed

benchmark/fs/bench-writevSync.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const fs = require('fs');
5+
const assert = require('assert');
6+
const tmpdir = require('../../test/common/tmpdir');
7+
tmpdir.refresh();
8+
9+
const path = tmpdir.resolve(`new-file-${process.pid}`);
10+
fs.writeFileSync(path, 'Some content.');
11+
12+
const bench = common.createBenchmark(main, {
13+
type: ['valid', 'invalid'],
14+
n: [1e5],
15+
});
16+
17+
const buffer = Buffer.from('Benchmark data.');
18+
19+
function main({ n, type }) {
20+
let fd;
21+
let result;
22+
switch (type) {
23+
case 'valid':
24+
fd = fs.openSync(path, 'r+');
25+
26+
bench.start();
27+
for (let i = 0; i < n; i++) {
28+
try {
29+
result = fs.writevSync(fd, [buffer]);
30+
} catch {
31+
//
32+
}
33+
}
34+
bench.end(n);
35+
assert(result);
36+
fs.closeSync(fd);
37+
break;
38+
case 'invalid':
39+
fd = tmpdir.resolve(`.non-existing-file-${process.pid}`);
40+
let hasError = false;
41+
bench.start();
42+
for (let i = 0; i < n; i++) {
43+
try {
44+
result = fs.writevSync(fd, [buffer]);
45+
} catch {
46+
hasError = true;
47+
}
48+
}
49+
bench.end(n);
50+
assert(hasError);
51+
52+
break;
53+
default:
54+
throw new Error('Invalid type');
55+
}
56+
}

lib/fs.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -998,15 +998,10 @@ function writevSync(fd, buffers, position) {
998998
return 0;
999999
}
10001000

1001-
const ctx = {};
1002-
10031001
if (typeof position !== 'number')
10041002
position = null;
10051003

1006-
const result = binding.writeBuffers(fd, buffers, position, undefined, ctx);
1007-
1008-
handleErrorFromBinding(ctx);
1009-
return result;
1004+
return binding.writeBuffers(fd, buffers, position);
10101005
}
10111006

10121007
/**

src/node_file.cc

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,18 +2205,20 @@ static void WriteBuffers(const FunctionCallbackInfo<Value>& args) {
22052205
iovs[i] = uv_buf_init(Buffer::Data(chunk), Buffer::Length(chunk));
22062206
}
22072207

2208-
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
2209-
if (req_wrap_async != nullptr) { // writeBuffers(fd, chunks, pos, req)
2210-
FS_ASYNC_TRACE_BEGIN0(UV_FS_WRITE, req_wrap_async)
2211-
AsyncCall(env, req_wrap_async, args, "write", UTF8, AfterInteger,
2208+
if (argc > 3) { // writeBuffers(fd, chunks, pos, req)
2209+
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
2210+
FS_ASYNC_TRACE_BEGIN0(UV_FS_WRITE, req_wrap_async)
2211+
AsyncCall(env, req_wrap_async, args, "write", UTF8, AfterInteger,
22122212
uv_fs_write, fd, *iovs, iovs.length(), pos);
2213-
} else { // writeBuffers(fd, chunks, pos, undefined, ctx)
2214-
CHECK_EQ(argc, 5);
2215-
FSReqWrapSync req_wrap_sync;
2213+
} else { // writeBuffers(fd, chunks, pos)
2214+
FSReqWrapSync req_wrap_sync("write");
22162215
FS_SYNC_TRACE_BEGIN(write);
2217-
int bytesWritten = SyncCall(env, args[4], &req_wrap_sync, "write",
2216+
int bytesWritten = SyncCallAndThrowOnError(env, &req_wrap_sync,
22182217
uv_fs_write, fd, *iovs, iovs.length(), pos);
22192218
FS_SYNC_TRACE_END(write, "bytesWritten", bytesWritten);
2219+
if (is_uv_error(bytesWritten)) {
2220+
return;
2221+
}
22202222
args.GetReturnValue().Set(bytesWritten);
22212223
}
22222224
}

0 commit comments

Comments
 (0)