Skip to content

Commit

Permalink
tools/api: Speed up fmt from 1min to 18s by writing to rustfmt stdin
Browse files Browse the repository at this point in the history
This reintroduces the "pipe Rust code through rustfmt before writing to
disk" code from [#828] and yields a massive performance improvement for
running in parallel over all files now, and not having to write, read,
and write the same files over again.

Unfortunately Rust's `Command` structure does not yet have proper
support for forwarding stdout to a file (that's not unix-specific),
though it could possibly be beneficial to write chunks read from stdout
directly to a file instead of reading the whole lot into memory first.

[#828]: #828
  • Loading branch information
MarijnS95 committed Oct 28, 2021
1 parent e96158e commit 3ecd976
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 13 deletions.
29 changes: 17 additions & 12 deletions crates/tools/api/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,6 @@ fn main() {

write_toml(&output, root);
println!("Elapsed: {} ms", start.elapsed().as_millis());
let start = std::time::Instant::now();

// rustfmt doesn't work reliably in parallel so have to run cargo fmt at the end, very slowly...
println!("\ncargo fmt...");
let mut cmd = ::std::process::Command::new("cargo");
output.pop();
cmd.current_dir(output);
cmd.arg("fmt");
cmd.output().unwrap();

println!("Elapsed: {} ms", start.elapsed().as_millis());
}

fn write_toml(output: &std::path::Path, tree: &reader::TypeTree) {
Expand Down Expand Up @@ -149,5 +138,21 @@ fn gen_tree(output: &std::path::Path, root: &'static str, tree: &reader::TypeTre
path.push("mod.rs");

let tokens = gen::gen_source_file(root, tree);
std::fs::write(&path, tokens.into_string().as_bytes()).unwrap();

let mut child = std::process::Command::new("rustfmt")
.stdin(std::process::Stdio::piped())
.stdout(std::process::Stdio::piped())
.spawn()
.expect("Failed to spawn `rustfmt`");
let mut stdin = child.stdin.take().expect("Failed to open stdin");
stdin.write_all(tokens.into_string().as_bytes()).unwrap();
drop(stdin);

let output = child.wait_with_output().unwrap();
assert!(output.status.success());
std::fs::write(
&path,
String::from_utf8(output.stdout).expect("Failed to parse UTF-8"),
)
.unwrap();
}
2 changes: 1 addition & 1 deletion src/Windows/Win32/Foundation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ impl ::std::default::Default for BSTR {
}
impl ::std::fmt::Display for BSTR {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
use ::std::fmt::Write;
use std::fmt::Write;
for c in ::std::char::decode_utf16(self.as_wide().iter().cloned()) {
f.write_char(c.map_err(|_| ::std::fmt::Error)?)?
}
Expand Down

0 comments on commit 3ecd976

Please sign in to comment.