diff --git a/cli/bench/write_file.js b/cli/bench/write_file.js new file mode 100644 index 0000000000..2f09b36451 --- /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 893b8b2c3e..36bd317b79 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 1637c20c0b..b63ddfd69e 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, - 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, - append: bool, - create: bool, - data: ZeroCopyBuf, - cancel_rid: Option, -} - -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, + 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>, - args: WriteFileArgs, + path: String, + mode: Option, + append: bool, + create: bool, + data: ZeroCopyBuf, + cancel_rid: Option, ) -> 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, 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