From 078def0ff8501bb07f3f286515acd8c6a2181037 Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Wed, 17 Jul 2024 05:35:51 -0700 Subject: perf(ext/node): optimize fs.exists[Sync] (#24613) Use `access` on *nix and `GetFileAttributesW` on Windows. [Benchmark](https://paste.divy.work/p/-gq8Ark.js): ``` $ deno run -A bench.mjs # main (568dd) existsSync: 8980.636629ms $ target/release/deno run -A bench.mjs # this PR existsSync: 6448.7604519999995ms $ bun bench.mjs existsSync: 6562.88671ms $ node bench.mjs existsSync: 7740.064653ms ``` Ref https://github.com/denoland/deno/pull/24434#discussion_r1679777912 --- ext/node/lib.rs | 1 + ext/node/ops/fs.rs | 23 ++++++++++++++++++++++- ext/node/polyfills/_fs/_fs_exists.ts | 4 ++-- 3 files changed, 25 insertions(+), 3 deletions(-) (limited to 'ext/node') diff --git a/ext/node/lib.rs b/ext/node/lib.rs index 13f9abc60..5be0fffa1 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -313,6 +313,7 @@ deno_core::extension!(deno_node, ops::crypto::x509::op_node_x509_get_serial_number, ops::crypto::x509::op_node_x509_key_usage, ops::fs::op_node_fs_exists_sync

, + ops::fs::op_node_fs_exists

, ops::fs::op_node_cp_sync

, ops::fs::op_node_cp

, ops::fs::op_node_lchown_sync

, diff --git a/ext/node/ops/fs.rs b/ext/node/ops/fs.rs index 47b66ee1d..687903325 100644 --- a/ext/node/ops/fs.rs +++ b/ext/node/ops/fs.rs @@ -26,7 +26,28 @@ where .borrow_mut::

() .check_read_with_api_name(&path, Some("node:fs.existsSync()"))?; let fs = state.borrow::(); - Ok(fs.lstat_sync(&path).is_ok()) + Ok(fs.exists_sync(&path)) +} + +#[op2(async)] +pub async fn op_node_fs_exists

( + state: Rc>, + #[string] path: String, +) -> Result +where + P: NodePermissions + 'static, +{ + let path = PathBuf::from(path); + + let fs = { + let mut state = state.borrow_mut(); + state + .borrow_mut::

() + .check_read_with_api_name(&path, Some("node:fs.exists()"))?; + state.borrow::().clone() + }; + + Ok(fs.exists_async(path).await?) } #[op2(fast)] diff --git a/ext/node/polyfills/_fs/_fs_exists.ts b/ext/node/polyfills/_fs/_fs_exists.ts index 57df1f07c..b5bbe235a 100644 --- a/ext/node/polyfills/_fs/_fs_exists.ts +++ b/ext/node/polyfills/_fs/_fs_exists.ts @@ -3,7 +3,7 @@ // TODO(petamoriken): enable prefer-primordials for node polyfills // deno-lint-ignore-file prefer-primordials -import { op_node_fs_exists_sync } from "ext:core/ops"; +import { op_node_fs_exists, op_node_fs_exists_sync } from "ext:core/ops"; import { pathFromURL } from "ext:deno_web/00_infra.js"; @@ -16,7 +16,7 @@ type ExistsCallback = (exists: boolean) => void; */ export function exists(path: string | URL, callback: ExistsCallback) { path = path instanceof URL ? pathFromURL(path) : path; - Deno.lstat(path).then(() => callback(true), () => callback(false)); + op_node_fs_exists(path).then(callback); } // The callback of fs.exists doesn't have standard callback signature. -- cgit v1.2.3