summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2022-09-05 17:20:48 +0530
committerGitHub <noreply@github.com>2022-09-05 17:20:48 +0530
commit1cdd2504b1cebc8ecf50f65f57959765e2a7b328 (patch)
tree138d4df0ae7cd7bd6fa71a0cd8e1c9df35cdc242
parent264ad49e18161a29cf8831dff2e4bcbcea59d086 (diff)
perf(runtime): flatten arguments for write_file ops (#15776)
-rw-r--r--cli/bench/write_file.js21
-rw-r--r--runtime/js/40_write_file.js25
-rw-r--r--runtime/ops/fs.rs82
3 files changed, 65 insertions, 63 deletions
diff --git a/cli/bench/write_file.js b/cli/bench/write_file.js
new file mode 100644
index 000000000..2f09b3645
--- /dev/null
+++ b/cli/bench/write_file.js
@@ -0,0 +1,21 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+const queueMicrotask = globalThis.queueMicrotask || process.nextTick;
+let [total, count] = typeof Deno !== "undefined"
+ ? Deno.args
+ : [process.argv[2], process.argv[3]];
+
+total = total ? parseInt(total, 0) : 50;
+count = count ? parseInt(count, 10) : 10000;
+
+async function bench(fun) {
+ const start = Date.now();
+ for (let i = 0; i < count; i++) await fun();
+ const elapsed = Date.now() - start;
+ const rate = Math.floor(count / (elapsed / 1000));
+ console.log(`time ${elapsed} ms rate ${rate}`);
+ if (--total) queueMicrotask(() => bench(fun));
+}
+
+bench(() => Deno.writeFile("/dev/null", new Uint8Array(10)));
+// const fs = require("fs").promises;
+// bench(() => fs.writeFile("/dev/null", new Uint8Array(10)));
diff --git a/runtime/js/40_write_file.js b/runtime/js/40_write_file.js
index 893b8b2c3..36bd317b7 100644
--- a/runtime/js/40_write_file.js
+++ b/runtime/js/40_write_file.js
@@ -12,13 +12,13 @@
options = {},
) {
options.signal?.throwIfAborted();
- ops.op_write_file_sync({
- path: pathFromURL(path),
+ ops.op_write_file_sync(
+ pathFromURL(path),
+ options.mode,
+ options.append ?? false,
+ options.create ?? true,
data,
- mode: options.mode,
- append: options.append ?? false,
- create: options.create ?? true,
- });
+ );
}
async function writeFile(
@@ -35,14 +35,15 @@
options.signal[abortSignal.add](abortHandler);
}
try {
- await core.opAsync("op_write_file_async", {
- path: pathFromURL(path),
+ await core.opAsync(
+ "op_write_file_async",
+ pathFromURL(path),
+ options.mode,
+ options.append ?? false,
+ options.create ?? true,
data,
- mode: options.mode,
- append: options.append ?? false,
- create: options.create ?? true,
cancelRid,
- });
+ );
} finally {
if (options.signal) {
options.signal[abortSignal.remove](abortHandler);
diff --git a/runtime/ops/fs.rs b/runtime/ops/fs.rs
index 1637c20c0..b63ddfd69 100644
--- a/runtime/ops/fs.rs
+++ b/runtime/ops/fs.rs
@@ -108,14 +108,6 @@ pub fn init() -> Extension {
.build()
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct OpenArgs {
- path: String,
- mode: Option<u32>,
- options: OpenOptions,
-}
-
#[derive(Deserialize, Default, Debug)]
#[serde(rename_all = "camelCase")]
#[serde(default)]
@@ -222,58 +214,47 @@ async fn op_open_async(
Ok(rid)
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct WriteFileArgs {
- path: String,
- mode: Option<u32>,
- append: bool,
- create: bool,
- data: ZeroCopyBuf,
- cancel_rid: Option<ResourceId>,
-}
-
-impl WriteFileArgs {
- fn into_open_args_and_data(self) -> (OpenArgs, ZeroCopyBuf) {
- (
- OpenArgs {
- path: self.path,
- mode: self.mode,
- options: OpenOptions {
- read: false,
- write: true,
- create: self.create,
- truncate: !self.append,
- append: self.append,
- create_new: false,
- },
- },
- self.data,
- )
+#[inline]
+fn write_open_options(create: bool, append: bool) -> OpenOptions {
+ OpenOptions {
+ read: false,
+ write: true,
+ create,
+ truncate: !append,
+ append,
+ create_new: false,
}
}
#[op]
fn op_write_file_sync(
state: &mut OpState,
- args: WriteFileArgs,
+ path: String,
+ mode: Option<u32>,
+ append: bool,
+ create: bool,
+ data: ZeroCopyBuf,
) -> Result<(), AnyError> {
- let (open_args, data) = args.into_open_args_and_data();
let (path, open_options) = open_helper(
state,
- &open_args.path,
- open_args.mode,
- Some(&open_args.options),
+ &path,
+ mode,
+ Some(&write_open_options(create, append)),
)?;
- write_file(&path, open_options, &open_args, data)
+ write_file(&path, open_options, mode, data)
}
#[op]
async fn op_write_file_async(
state: Rc<RefCell<OpState>>,
- args: WriteFileArgs,
+ path: String,
+ mode: Option<u32>,
+ append: bool,
+ create: bool,
+ data: ZeroCopyBuf,
+ cancel_rid: Option<ResourceId>,
) -> Result<(), AnyError> {
- let cancel_handle = match args.cancel_rid {
+ let cancel_handle = match cancel_rid {
Some(cancel_rid) => state
.borrow_mut()
.resource_table
@@ -281,15 +262,14 @@ async fn op_write_file_async(
.ok(),
None => None,
};
- let (open_args, data) = args.into_open_args_and_data();
let (path, open_options) = open_helper(
&mut *state.borrow_mut(),
- &open_args.path,
- open_args.mode,
- Some(&open_args.options),
+ &path,
+ mode,
+ Some(&write_open_options(create, append)),
)?;
let write_future = tokio::task::spawn_blocking(move || {
- write_file(&path, open_options, &open_args, data)
+ write_file(&path, open_options, mode, data)
});
if let Some(cancel_handle) = cancel_handle {
write_future.or_cancel(cancel_handle).await???;
@@ -302,7 +282,7 @@ async fn op_write_file_async(
fn write_file(
path: &Path,
open_options: std::fs::OpenOptions,
- _open_args: &OpenArgs,
+ _mode: Option<u32>,
data: ZeroCopyBuf,
) -> Result<(), AnyError> {
let mut std_file = open_options.open(path).map_err(|err| {
@@ -311,7 +291,7 @@ fn write_file(
// need to chmod the file if it already exists and a mode is specified
#[cfg(unix)]
- if let Some(mode) = &_open_args.mode {
+ if let Some(mode) = _mode {
use std::os::unix::fs::PermissionsExt;
let permissions = PermissionsExt::from_mode(mode & 0o777);
std_file