Skip to content

Commit 6bd77db

Browse files
CanadaHonkanonrig
authored andcommitted
fs: improve error perf of sync *times
PR-URL: #49864 Refs: nodejs/performance#106 Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: Joyee Cheung <[email protected]>
1 parent a85e418 commit 6bd77db

File tree

4 files changed

+97
-41
lines changed

4 files changed

+97
-41
lines changed

benchmark/fs/bench-timesSync.js

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const fs = require('fs');
5+
const tmpdir = require('../../test/common/tmpdir');
6+
tmpdir.refresh();
7+
8+
const bench = common.createBenchmark(main, {
9+
type: ['existing', 'non-existing'],
10+
func: [ 'utimes', 'futimes', 'lutimes' ],
11+
n: [1e3],
12+
});
13+
14+
function main({ n, type, func }) {
15+
const useFds = func === 'futimes';
16+
const fsFunc = fs[func + 'Sync'];
17+
18+
switch (type) {
19+
case 'existing': {
20+
const files = [];
21+
22+
// Populate tmpdir with mock files
23+
for (let i = 0; i < n; i++) {
24+
const path = tmpdir.resolve(`timessync-bench-file-${i}`);
25+
fs.writeFileSync(path, 'bench');
26+
files.push(useFds ? fs.openSync(path, 'r+') : path);
27+
}
28+
29+
bench.start();
30+
for (let i = 0; i < n; i++) {
31+
fsFunc(files[i], i, i);
32+
}
33+
bench.end(n);
34+
35+
if (useFds) files.forEach((x) => {
36+
try {
37+
fs.closeSync(x);
38+
} catch {
39+
// do nothing
40+
}
41+
});
42+
43+
break;
44+
}
45+
case 'non-existing': {
46+
bench.start();
47+
for (let i = 0; i < n; i++) {
48+
try {
49+
fsFunc(useFds ? (1 << 30) : tmpdir.resolve(`.non-existing-file-${Date.now()}`), i, i);
50+
} catch {
51+
// do nothing
52+
}
53+
}
54+
bench.end(n);
55+
56+
break;
57+
}
58+
default:
59+
new Error('Invalid type');
60+
}
61+
}

lib/fs.js

+15-17
Original file line numberDiff line numberDiff line change
@@ -2125,11 +2125,11 @@ function utimes(path, atime, mtime, callback) {
21252125
*/
21262126
function utimesSync(path, atime, mtime) {
21272127
path = getValidatedPath(path);
2128-
const ctx = { path };
2129-
binding.utimes(pathModule.toNamespacedPath(path),
2130-
toUnixTimestamp(atime), toUnixTimestamp(mtime),
2131-
undefined, ctx);
2132-
handleErrorFromBinding(ctx);
2128+
binding.utimes(
2129+
pathModule.toNamespacedPath(path),
2130+
toUnixTimestamp(atime),
2131+
toUnixTimestamp(mtime),
2132+
);
21332133
}
21342134

21352135
/**
@@ -2162,12 +2162,11 @@ function futimes(fd, atime, mtime, callback) {
21622162
* @returns {void}
21632163
*/
21642164
function futimesSync(fd, atime, mtime) {
2165-
fd = getValidatedFd(fd);
2166-
atime = toUnixTimestamp(atime, 'atime');
2167-
mtime = toUnixTimestamp(mtime, 'mtime');
2168-
const ctx = {};
2169-
binding.futimes(fd, atime, mtime, undefined, ctx);
2170-
handleErrorFromBinding(ctx);
2165+
binding.futimes(
2166+
getValidatedFd(fd),
2167+
toUnixTimestamp(atime, 'atime'),
2168+
toUnixTimestamp(mtime, 'mtime'),
2169+
);
21712170
}
21722171

21732172
/**
@@ -2201,12 +2200,11 @@ function lutimes(path, atime, mtime, callback) {
22012200
*/
22022201
function lutimesSync(path, atime, mtime) {
22032202
path = getValidatedPath(path);
2204-
const ctx = { path };
2205-
binding.lutimes(pathModule.toNamespacedPath(path),
2206-
toUnixTimestamp(atime),
2207-
toUnixTimestamp(mtime),
2208-
undefined, ctx);
2209-
handleErrorFromBinding(ctx);
2203+
binding.lutimes(
2204+
pathModule.toNamespacedPath(path),
2205+
toUnixTimestamp(atime),
2206+
toUnixTimestamp(mtime),
2207+
);
22102208
}
22112209

22122210
function writeAll(fd, isUserFd, buffer, offset, length, signal, flush, callback) {

src/node_file.cc

+18-21
Original file line numberDiff line numberDiff line change
@@ -2686,18 +2686,17 @@ static void UTimes(const FunctionCallbackInfo<Value>& args) {
26862686
CHECK(args[2]->IsNumber());
26872687
const double mtime = args[2].As<Number>()->Value();
26882688

2689-
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
2690-
if (req_wrap_async != nullptr) { // utimes(path, atime, mtime, req)
2689+
if (argc > 3) { // utimes(path, atime, mtime, req)
2690+
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
26912691
FS_ASYNC_TRACE_BEGIN1(
26922692
UV_FS_UTIME, req_wrap_async, "path", TRACE_STR_COPY(*path))
26932693
AsyncCall(env, req_wrap_async, args, "utime", UTF8, AfterNoArgs,
26942694
uv_fs_utime, *path, atime, mtime);
2695-
} else { // utimes(path, atime, mtime, undefined, ctx)
2696-
CHECK_EQ(argc, 5);
2697-
FSReqWrapSync req_wrap_sync;
2695+
} else { // utimes(path, atime, mtime)
2696+
FSReqWrapSync req_wrap_sync("utime", *path);
26982697
FS_SYNC_TRACE_BEGIN(utimes);
2699-
SyncCall(env, args[4], &req_wrap_sync, "utime",
2700-
uv_fs_utime, *path, atime, mtime);
2698+
SyncCallAndThrowOnError(
2699+
env, &req_wrap_sync, uv_fs_utime, *path, atime, mtime);
27012700
FS_SYNC_TRACE_END(utimes);
27022701
}
27032702
}
@@ -2717,17 +2716,16 @@ static void FUTimes(const FunctionCallbackInfo<Value>& args) {
27172716
CHECK(args[2]->IsNumber());
27182717
const double mtime = args[2].As<Number>()->Value();
27192718

2720-
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
2721-
if (req_wrap_async != nullptr) { // futimes(fd, atime, mtime, req)
2719+
if (argc > 3) { // futimes(fd, atime, mtime, req)
2720+
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
27222721
FS_ASYNC_TRACE_BEGIN0(UV_FS_FUTIME, req_wrap_async)
27232722
AsyncCall(env, req_wrap_async, args, "futime", UTF8, AfterNoArgs,
27242723
uv_fs_futime, fd, atime, mtime);
2725-
} else { // futimes(fd, atime, mtime, undefined, ctx)
2726-
CHECK_EQ(argc, 5);
2727-
FSReqWrapSync req_wrap_sync;
2724+
} else { // futimes(fd, atime, mtime)
2725+
FSReqWrapSync req_wrap_sync("futime");
27282726
FS_SYNC_TRACE_BEGIN(futimes);
2729-
SyncCall(env, args[4], &req_wrap_sync, "futime",
2730-
uv_fs_futime, fd, atime, mtime);
2727+
SyncCallAndThrowOnError(
2728+
env, &req_wrap_sync, uv_fs_futime, fd, atime, mtime);
27312729
FS_SYNC_TRACE_END(futimes);
27322730
}
27332731
}
@@ -2749,18 +2747,17 @@ static void LUTimes(const FunctionCallbackInfo<Value>& args) {
27492747
CHECK(args[2]->IsNumber());
27502748
const double mtime = args[2].As<Number>()->Value();
27512749

2752-
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
2753-
if (req_wrap_async != nullptr) { // lutimes(path, atime, mtime, req)
2750+
if (argc > 3) { // lutimes(path, atime, mtime, req)
2751+
FSReqBase* req_wrap_async = GetReqWrap(args, 3);
27542752
FS_ASYNC_TRACE_BEGIN1(
27552753
UV_FS_LUTIME, req_wrap_async, "path", TRACE_STR_COPY(*path))
27562754
AsyncCall(env, req_wrap_async, args, "lutime", UTF8, AfterNoArgs,
27572755
uv_fs_lutime, *path, atime, mtime);
2758-
} else { // lutimes(path, atime, mtime, undefined, ctx)
2759-
CHECK_EQ(argc, 5);
2760-
FSReqWrapSync req_wrap_sync;
2756+
} else { // lutimes(path, atime, mtime)
2757+
FSReqWrapSync req_wrap_sync("lutime", *path);
27612758
FS_SYNC_TRACE_BEGIN(lutimes);
2762-
SyncCall(env, args[4], &req_wrap_sync, "lutime",
2763-
uv_fs_lutime, *path, atime, mtime);
2759+
SyncCallAndThrowOnError(
2760+
env, &req_wrap_sync, uv_fs_lutime, *path, atime, mtime);
27642761
FS_SYNC_TRACE_END(lutimes);
27652762
}
27662763
}

typings/internalBinding/fs.d.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ declare namespace InternalFSBinding {
107107
function ftruncate(fd: number, len: number, usePromises: typeof kUsePromises): Promise<void>;
108108

109109
function futimes(fd: number, atime: number, mtime: number, req: FSReqCallback): void;
110-
function futimes(fd: number, atime: number, mtime: number, req: undefined, ctx: FSSyncContext): void;
110+
function futimes(fd: number, atime: number, mtime: number): void;
111111
function futimes(fd: number, atime: number, mtime: number, usePromises: typeof kUsePromises): Promise<void>;
112112

113113
function internalModuleReadJSON(path: string): [] | [string, boolean];
@@ -132,7 +132,7 @@ declare namespace InternalFSBinding {
132132
function lstat(path: StringOrBuffer, useBigint: false, usePromises: typeof kUsePromises): Promise<Float64Array>;
133133

134134
function lutimes(path: string, atime: number, mtime: number, req: FSReqCallback): void;
135-
function lutimes(path: string, atime: number, mtime: number, req: undefined, ctx: FSSyncContext): void;
135+
function lutimes(path: string, atime: number, mtime: number): void;
136136
function lutimes(path: string, atime: number, mtime: number, usePromises: typeof kUsePromises): Promise<void>;
137137

138138
function mkdtemp(prefix: string, encoding: unknown, req: FSReqCallback<string>): void;
@@ -207,7 +207,7 @@ declare namespace InternalFSBinding {
207207
function unlink(path: string, usePromises: typeof kUsePromises): Promise<void>;
208208

209209
function utimes(path: string, atime: number, mtime: number, req: FSReqCallback): void;
210-
function utimes(path: string, atime: number, mtime: number, req: undefined, ctx: FSSyncContext): void;
210+
function utimes(path: string, atime: number, mtime: number): void;
211211
function utimes(path: string, atime: number, mtime: number, usePromises: typeof kUsePromises): Promise<void>;
212212

213213
function writeBuffer(fd: number, buffer: ArrayBufferView, offset: number, length: number, position: number | null, req: FSReqCallback<number>): void;

0 commit comments

Comments
 (0)