aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Tolnay <dtolnay@gmail.com>2019-06-23 15:50:02 -0700
committerDavid Tolnay <dtolnay@gmail.com>2019-06-23 16:45:06 -0700
commita6995ba7361d148682fa947fd4bcd1212778aa81 (patch)
treef6fca7843b565654bc8c9e925069a5f9e42d680e
parentfb8255e14418425f97b0c0a5da9074cc42f5cb69 (diff)
downloadsyn-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.toml6
-rw-r--r--benches/rust.rs106
-rw-r--r--tests/common/mod.rs1
3 files changed, 112 insertions, 1 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 1ca12ee9..a394b8d2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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());
}