mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 15:49:44 -05:00
perf(runtime): flatten arguments for write_file ops (#15776)
This commit is contained in:
parent
264ad49e18
commit
1cdd2504b1
3 changed files with 65 additions and 63 deletions
21
cli/bench/write_file.js
Normal file
21
cli/bench/write_file.js
Normal file
|
@ -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)));
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue