diff options
author | David Tolnay <dtolnay@gmail.com> | 2019-06-23 15:50:02 -0700 |
---|---|---|
committer | David Tolnay <dtolnay@gmail.com> | 2019-06-23 16:45:06 -0700 |
commit | a6995ba7361d148682fa947fd4bcd1212778aa81 (patch) | |
tree | f6fca7843b565654bc8c9e925069a5f9e42d680e | |
parent | fb8255e14418425f97b0c0a5da9074cc42f5cb69 (diff) | |
download | syn-a6995ba7361d148682fa947fd4bcd1212778aa81.tar.gz |
Add benchmark of parsing whole rust repo
On my machine:
tokenstream_parse: elapsed=1.453s
syn_parse: elapsed=4.632s
libsyntax_parse: elapsed=2.039s
-rw-r--r-- | Cargo.toml | 6 | ||||
-rw-r--r-- | benches/rust.rs | 106 | ||||
-rw-r--r-- | tests/common/mod.rs | 1 |
3 files changed, 112 insertions, 1 deletions
@@ -43,6 +43,12 @@ regex = "1.0" termcolor = "1.0" walkdir = "2.1" +[[bench]] +name = "rust" +edition = "2018" +harness = false +required-features = ["full", "parsing"] + [package.metadata.docs.rs] all-features = true diff --git a/benches/rust.rs b/benches/rust.rs new file mode 100644 index 00000000..2a5005e8 --- /dev/null +++ b/benches/rust.rs @@ -0,0 +1,106 @@ +// $ cargo bench --features full + +#![recursion_limit = "256"] +#![feature(rustc_private)] + +extern crate rustc_data_structures; +extern crate syntax; +extern crate syntax_pos; + +#[macro_use] +#[path = "../tests/macros/mod.rs"] +mod macros; + +#[path = "../tests/common/mod.rs"] +mod common; + +use proc_macro2::TokenStream; +use rustc_data_structures::sync::Lrc; +use std::str::FromStr; +use std::time::{Duration, Instant}; +use syntax::edition::Edition; +use syntax::errors::{emitter::Emitter, DiagnosticBuilder, Handler}; +use syntax::parse::ParseSess; +use syntax::source_map::{FilePathMapping, SourceMap}; +use syntax_pos::FileName; + +fn tokenstream_parse(content: &str) -> Result<(), ()> { + TokenStream::from_str(content).map(drop).map_err(drop) +} + +fn syn_parse(content: &str) -> Result<(), ()> { + syn::parse_file(content).map(drop).map_err(drop) +} + +fn libsyntax_parse(content: &str) -> Result<(), ()> { + struct SilentEmitter; + + impl Emitter for SilentEmitter { + fn emit_diagnostic(&mut self, _db: &DiagnosticBuilder) {} + } + + syntax::with_globals(Edition::Edition2018, || { + let cm = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let emitter = Box::new(SilentEmitter); + let handler = Handler::with_emitter(false, None, emitter); + let sess = ParseSess::with_span_handler(handler, cm); + if let Err(mut diagnostic) = syntax::parse::parse_crate_from_source_str( + FileName::Custom("bench".to_owned()), + content.to_owned(), + &sess, + ) { + diagnostic.cancel(); + return Err(()); + }; + Ok(()) + }) +} + +fn exec(codepath: fn(&str) -> Result<(), ()>) -> Duration { + let begin = Instant::now(); + let mut success = 0; + let mut total = 0; + + walkdir::WalkDir::new("tests/rust/src") + .into_iter() + .filter_entry(common::base_dir_filter) + .for_each(|entry| { + let entry = entry.unwrap(); + let path = entry.path(); + if path.is_dir() { + return; + } + let content = std::fs::read_to_string(path).unwrap(); + let ok = codepath(&content).is_ok(); + success += ok as usize; + total += 1; + if !ok { + eprintln!("FAIL {}", path.display()); + } + }); + + assert_eq!(success, total); + begin.elapsed() +} + +fn main() { + common::clone_rust(); + + macro_rules! testcases { + ($($name:ident),*) => { + vec![ + $( + (stringify!($name), $name as fn(&str) -> Result<(), ()>), + )* + ] + }; + } + + eprintln!(); + for (name, f) in testcases!(tokenstream_parse, syn_parse, libsyntax_parse) { + eprint!("{:20}", format!("{}:", name)); + let elapsed = exec(f); + eprintln!("elapsed={}.{:03}s", elapsed.as_secs(), elapsed.subsec_millis()); + } + eprintln!(); +} diff --git a/tests/common/mod.rs b/tests/common/mod.rs index c066510c..84b317a4 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -66,6 +66,5 @@ pub fn base_dir_filter(entry: &DirEntry) -> bool { pub fn clone_rust() { let result = Command::new("tests/clone.sh").status().unwrap(); - println!("result: {}", result); assert!(result.success()); } |