mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
perf(cli): faster standalone executable determination (#22717)
This was showing up on the flamegraph. ``` 14:54 $ hyperfine -S none --warmup 25 '/tmp/deno run /tmp/empty.js' 'target/release/deno run /tmp/empty.js' Benchmark 1: /tmp/deno run /tmp/empty.js Time (mean ± σ): 17.2 ms ± 4.7 ms [User: 11.2 ms, System: 4.0 ms] Range (min … max): 15.1 ms … 72.9 ms 172 runs Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options. Benchmark 2: target/release/deno run /tmp/empty.js Time (mean ± σ): 16.7 ms ± 1.1 ms [User: 11.1 ms, System: 4.0 ms] Range (min … max): 15.0 ms … 20.1 ms 189 runs Summary 'target/release/deno run /tmp/empty.js' ran 1.03 ± 0.29 times faster than '/tmp/deno run /tmp/empty.js' ✔ ~/Documents/github/deno/deno [faster_extract|…5⚑ 23] ```
This commit is contained in:
parent
3333d67335
commit
3fd4b882a4
3 changed files with 54 additions and 41 deletions
14
cli/main.rs
14
cli/main.rs
|
@ -322,13 +322,15 @@ pub fn main() {
|
||||||
// initialize the V8 platform on a parent thread of all threads that will spawn
|
// initialize the V8 platform on a parent thread of all threads that will spawn
|
||||||
// V8 isolates.
|
// V8 isolates.
|
||||||
|
|
||||||
|
let current_exe_path = current_exe().unwrap();
|
||||||
|
let standalone =
|
||||||
|
standalone::extract_standalone(¤t_exe_path, args.clone());
|
||||||
let future = async move {
|
let future = async move {
|
||||||
let current_exe_path = current_exe()?;
|
let standalone_res = match standalone {
|
||||||
let standalone_res =
|
Ok(Some(future)) => {
|
||||||
match standalone::extract_standalone(¤t_exe_path, args.clone())
|
let (metadata, eszip) = future.await?;
|
||||||
.await
|
standalone::run(eszip, metadata).await
|
||||||
{
|
}
|
||||||
Ok(Some((metadata, eszip))) => standalone::run(eszip, metadata).await,
|
|
||||||
Ok(None) => Ok(()),
|
Ok(None) => Ok(()),
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
};
|
};
|
||||||
|
|
|
@ -69,11 +69,16 @@ fn unwrap_or_exit<T>(result: Result<T, AnyError>) -> T {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
let future = async move {
|
|
||||||
let current_exe_path = current_exe().unwrap();
|
let current_exe_path = current_exe().unwrap();
|
||||||
match standalone::extract_standalone(¤t_exe_path, args).await {
|
let standalone =
|
||||||
Ok(Some((metadata, eszip))) => standalone::run(eszip, metadata).await,
|
standalone::extract_standalone(¤t_exe_path, args.clone());
|
||||||
Ok(None) => Err(generic_error("No archive found.")),
|
let future = async move {
|
||||||
|
match standalone {
|
||||||
|
Ok(Some(future)) => {
|
||||||
|
let (metadata, eszip) = future.await?;
|
||||||
|
standalone::run(eszip, metadata).await
|
||||||
|
}
|
||||||
|
Ok(None) => Ok(()),
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::env::current_exe;
|
use std::env::current_exe;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::future::Future;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::io::Seek;
|
use std::io::Seek;
|
||||||
use std::io::SeekFrom;
|
use std::io::SeekFrom;
|
||||||
|
@ -236,32 +237,36 @@ pub fn is_standalone_binary(exe_path: &Path) -> bool {
|
||||||
/// binary by skipping over the trailer width at the end of the file,
|
/// binary by skipping over the trailer width at the end of the file,
|
||||||
/// then checking for the magic trailer string `d3n0l4nd`. If found,
|
/// then checking for the magic trailer string `d3n0l4nd`. If found,
|
||||||
/// the bundle is executed. If not, this function exits with `Ok(None)`.
|
/// the bundle is executed. If not, this function exits with `Ok(None)`.
|
||||||
pub async fn extract_standalone(
|
pub fn extract_standalone(
|
||||||
exe_path: &Path,
|
exe_path: &Path,
|
||||||
cli_args: Vec<String>,
|
cli_args: Vec<String>,
|
||||||
) -> Result<Option<(Metadata, eszip::EszipV2)>, AnyError> {
|
) -> Result<
|
||||||
let file = std::fs::File::open(exe_path)?;
|
Option<impl Future<Output = Result<(Metadata, eszip::EszipV2), AnyError>>>,
|
||||||
|
AnyError,
|
||||||
let mut bufreader =
|
> {
|
||||||
deno_core::futures::io::BufReader::new(AllowStdIo::new(file));
|
// We do the first part sync so it can complete quickly
|
||||||
|
let mut file = std::fs::File::open(exe_path)?;
|
||||||
let _trailer_pos = bufreader
|
file.seek(SeekFrom::End(-(TRAILER_SIZE as i64)))?;
|
||||||
.seek(SeekFrom::End(-(TRAILER_SIZE as i64)))
|
|
||||||
.await?;
|
|
||||||
let mut trailer = [0; TRAILER_SIZE];
|
let mut trailer = [0; TRAILER_SIZE];
|
||||||
bufreader.read_exact(&mut trailer).await?;
|
file.read_exact(&mut trailer)?;
|
||||||
let trailer = match Trailer::parse(&trailer)? {
|
let trailer = match Trailer::parse(&trailer)? {
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
Some(trailer) => trailer,
|
Some(trailer) => trailer,
|
||||||
};
|
};
|
||||||
|
|
||||||
bufreader.seek(SeekFrom::Start(trailer.eszip_pos)).await?;
|
file.seek(SeekFrom::Start(trailer.eszip_pos))?;
|
||||||
|
|
||||||
|
// If we have an eszip, read it out
|
||||||
|
Ok(Some(async move {
|
||||||
|
let bufreader =
|
||||||
|
deno_core::futures::io::BufReader::new(AllowStdIo::new(file));
|
||||||
|
|
||||||
let (eszip, loader) = eszip::EszipV2::parse(bufreader)
|
let (eszip, loader) = eszip::EszipV2::parse(bufreader)
|
||||||
.await
|
.await
|
||||||
.context("Failed to parse eszip header")?;
|
.context("Failed to parse eszip header")?;
|
||||||
|
|
||||||
let mut bufreader = loader.await.context("Failed to parse eszip archive")?;
|
let mut bufreader =
|
||||||
|
loader.await.context("Failed to parse eszip archive")?;
|
||||||
|
|
||||||
bufreader
|
bufreader
|
||||||
.seek(SeekFrom::Start(trailer.metadata_pos))
|
.seek(SeekFrom::Start(trailer.metadata_pos))
|
||||||
|
@ -278,7 +283,8 @@ pub async fn extract_standalone(
|
||||||
let mut metadata: Metadata = serde_json::from_str(&metadata).unwrap();
|
let mut metadata: Metadata = serde_json::from_str(&metadata).unwrap();
|
||||||
metadata.argv.append(&mut cli_args[1..].to_vec());
|
metadata.argv.append(&mut cli_args[1..].to_vec());
|
||||||
|
|
||||||
Ok(Some((metadata, eszip)))
|
Ok((metadata, eszip))
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
const TRAILER_SIZE: usize = std::mem::size_of::<Trailer>() + 8; // 8 bytes for the magic trailer string
|
const TRAILER_SIZE: usize = std::mem::size_of::<Trailer>() + 8; // 8 bytes for the magic trailer string
|
||||||
|
|
Loading…
Reference in a new issue