From f7a160d5b44f19d731b69adbf83736517a0eeb7c Mon Sep 17 00:00:00 2001 From: Jungku Lee Date: Wed, 4 Oct 2023 09:19:13 +0900 Subject: [PATCH] fs: improve error performance for `fdatasyncSync` PR-URL: https://github.com/nodejs/node/pull/49898 Refs: https://github.com/nodejs/performance/issues/106 Reviewed-By: Yagiz Nizipli Reviewed-By: Joyee Cheung --- benchmark/fs/bench_fdatasyncSync.js | 42 +++++++++++++++++++++++++++++ lib/fs.js | 4 +-- src/node_file.cc | 14 +++++----- typings/internalBinding/fs.d.ts | 1 + 4 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 benchmark/fs/bench_fdatasyncSync.js diff --git a/benchmark/fs/bench_fdatasyncSync.js b/benchmark/fs/bench_fdatasyncSync.js new file mode 100644 index 00000000000000..9aedb0a314fb24 --- /dev/null +++ b/benchmark/fs/bench_fdatasyncSync.js @@ -0,0 +1,42 @@ +'use strict'; + +const common = require('../common'); +const fs = require('fs'); +const tmpdir = require('../../test/common/tmpdir'); +tmpdir.refresh(); + +const tmpfile = tmpdir.resolve(`.existing-file-${process.pid}`); +fs.writeFileSync(tmpfile, 'this-is-for-a-benchmark', 'utf8'); + +const bench = common.createBenchmark(main, { + type: ['existing', 'non-existing'], + n: [1e4], +}); + +function main({ n, type }) { + let fd; + + switch (type) { + case 'existing': + fd = fs.openSync(tmpfile, 'r', 0o666); + break; + case 'non-existing': + fd = 1 << 30; + break; + default: + new Error('Invalid type'); + } + + bench.start(); + for (let i = 0; i < n; i++) { + try { + fs.fdatasyncSync(fd); + } catch { + // do nothing + } + } + + bench.end(n); + + if (type === 'existing') fs.closeSync(fd); +} diff --git a/lib/fs.js b/lib/fs.js index 3ff5cff2d3fb9a..585458fddd6c1f 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1305,9 +1305,7 @@ function fdatasync(fd, callback) { */ function fdatasyncSync(fd) { fd = getValidatedFd(fd); - const ctx = {}; - binding.fdatasync(fd, undefined, ctx); - handleErrorFromBinding(ctx); + return binding.fdatasync(fd); } /** diff --git a/src/node_file.cc b/src/node_file.cc index 74476be54f9b5d..778e9139e4dc93 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -1501,21 +1501,21 @@ static void Fdatasync(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); const int argc = args.Length(); - CHECK_GE(argc, 2); + CHECK_GE(argc, 1); CHECK(args[0]->IsInt32()); const int fd = args[0].As()->Value(); - FSReqBase* req_wrap_async = GetReqWrap(args, 1); - if (req_wrap_async != nullptr) { + if (argc > 1) { // fdatasync(fd, req) + FSReqBase* req_wrap_async = GetReqWrap(args, 1); + CHECK_NOT_NULL(req_wrap_async); FS_ASYNC_TRACE_BEGIN0(UV_FS_FDATASYNC, req_wrap_async) AsyncCall(env, req_wrap_async, args, "fdatasync", UTF8, AfterNoArgs, uv_fs_fdatasync, fd); - } else { - CHECK_EQ(argc, 3); - FSReqWrapSync req_wrap_sync; + } else { // fdatasync(fd) + FSReqWrapSync req_wrap_sync("fdatasync"); FS_SYNC_TRACE_BEGIN(fdatasync); - SyncCall(env, args[2], &req_wrap_sync, "fdatasync", uv_fs_fdatasync, fd); + SyncCallAndThrowOnError(env, &req_wrap_sync, uv_fs_fdatasync, fd); FS_SYNC_TRACE_END(fdatasync); } } diff --git a/typings/internalBinding/fs.d.ts b/typings/internalBinding/fs.d.ts index a59045e33066cb..b4c4cd6e79a91c 100644 --- a/typings/internalBinding/fs.d.ts +++ b/typings/internalBinding/fs.d.ts @@ -86,6 +86,7 @@ declare namespace InternalFSBinding { function fdatasync(fd: number, req: FSReqCallback): void; function fdatasync(fd: number, req: undefined, ctx: FSSyncContext): void; function fdatasync(fd: number, usePromises: typeof kUsePromises): Promise; + function fdatasync(fd: number): void; function fstat(fd: number, useBigint: boolean, req: FSReqCallback): void; function fstat(fd: number, useBigint: true, req: FSReqCallback): void;