Skip to content

Commit

Permalink
fs: improve error performance of writevSync
Browse files Browse the repository at this point in the history
PR-URL: nodejs#50038
Refs: nodejs/performance#106
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
  • Loading branch information
IlyasShabi authored and debadree25 committed Apr 15, 2024
1 parent 128aae4 commit d75f4f9
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 15 deletions.
55 changes: 55 additions & 0 deletions benchmark/fs/bench-writevSync.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict';

const common = require('../common');
const fs = require('fs');
const assert = require('assert');
const tmpdir = require('../../test/common/tmpdir');
tmpdir.refresh();

const path = tmpdir.resolve(`new-file-${process.pid}`);
fs.writeFileSync(path, 'Some content.');

const bench = common.createBenchmark(main, {
type: ['valid', 'invalid'],
n: [1e5],
});

const buffer = Buffer.from('Benchmark data.');

function main({ n, type }) {
let fd;
let result;

switch (type) {
case 'valid':
fd = fs.openSync(path, 'r+');

bench.start();
for (let i = 0; i < n; i++) {
result = fs.writevSync(fd, [buffer]);
}

bench.end(n);
assert(result);
fs.closeSync(fd);
break;
case 'invalid': {
fd = 1 << 30;
let hasError = false;
bench.start();
for (let i = 0; i < n; i++) {
try {
result = fs.writevSync(fd, [buffer]);
} catch {
hasError = true;
}
}

bench.end(n);
assert(hasError);
break;
}
default:
throw new Error('Invalid type');
}
}
7 changes: 1 addition & 6 deletions lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -998,15 +998,10 @@ function writevSync(fd, buffers, position) {
return 0;
}

const ctx = {};

if (typeof position !== 'number')
position = null;

const result = binding.writeBuffers(fd, buffers, position, undefined, ctx);

handleErrorFromBinding(ctx);
return result;
return binding.writeBuffers(fd, buffers, position);
}

/**
Expand Down
29 changes: 20 additions & 9 deletions src/node_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2203,18 +2203,29 @@ static void WriteBuffers(const FunctionCallbackInfo<Value>& args) {
iovs[i] = uv_buf_init(Buffer::Data(chunk), Buffer::Length(chunk));
}

FSReqBase* req_wrap_async = GetReqWrap(args, 3);
if (req_wrap_async != nullptr) { // writeBuffers(fd, chunks, pos, req)
if (argc > 3) { // writeBuffers(fd, chunks, pos, req)
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
FS_ASYNC_TRACE_BEGIN0(UV_FS_WRITE, req_wrap_async)
AsyncCall(env, req_wrap_async, args, "write", UTF8, AfterInteger,
uv_fs_write, fd, *iovs, iovs.length(), pos);
} else { // writeBuffers(fd, chunks, pos, undefined, ctx)
CHECK_EQ(argc, 5);
FSReqWrapSync req_wrap_sync;
AsyncCall(env,
req_wrap_async,
args,
"write",
UTF8,
AfterInteger,
uv_fs_write,
fd,
*iovs,
iovs.length(),
pos);
} else { // writeBuffers(fd, chunks, pos)
FSReqWrapSync req_wrap_sync("write");
FS_SYNC_TRACE_BEGIN(write);
int bytesWritten = SyncCall(env, args[4], &req_wrap_sync, "write",
uv_fs_write, fd, *iovs, iovs.length(), pos);
int bytesWritten = SyncCallAndThrowOnError(
env, &req_wrap_sync, uv_fs_write, fd, *iovs, iovs.length(), pos);
FS_SYNC_TRACE_END(write, "bytesWritten", bytesWritten);
if (is_uv_error(bytesWritten)) {
return;
}
args.GetReturnValue().Set(bytesWritten);
}
}
Expand Down

0 comments on commit d75f4f9

Please sign in to comment.