aboutsummaryrefslogtreecommitdiff
path: root/vendor/syn/benches
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/syn/benches')
-rw-r--r--vendor/syn/benches/file.rs57
-rw-r--r--vendor/syn/benches/rust.rs182
2 files changed, 239 insertions, 0 deletions
diff --git a/vendor/syn/benches/file.rs b/vendor/syn/benches/file.rs
new file mode 100644
index 0000000..b424723
--- /dev/null
+++ b/vendor/syn/benches/file.rs
@@ -0,0 +1,57 @@
+// $ cargo bench --features full,test --bench file
+
+#![feature(rustc_private, test)]
+#![recursion_limit = "1024"]
+#![allow(
+ clippy::items_after_statements,
+ clippy::manual_let_else,
+ clippy::match_like_matches_macro,
+ clippy::missing_panics_doc,
+ clippy::must_use_candidate,
+ clippy::uninlined_format_args
+)]
+
+extern crate test;
+
+#[macro_use]
+#[path = "../tests/macros/mod.rs"]
+mod macros;
+
+#[allow(dead_code)]
+#[path = "../tests/repo/mod.rs"]
+mod repo;
+
+use proc_macro2::{Span, TokenStream};
+use std::fs;
+use std::str::FromStr;
+use syn::parse::{ParseStream, Parser};
+use test::Bencher;
+
+const FILE: &str = "tests/rust/library/core/src/str/mod.rs";
+
+fn get_tokens() -> TokenStream {
+ repo::clone_rust();
+ let content = fs::read_to_string(FILE).unwrap();
+ TokenStream::from_str(&content).unwrap()
+}
+
+#[bench]
+fn baseline(b: &mut Bencher) {
+ let tokens = get_tokens();
+ b.iter(|| drop(tokens.clone()));
+}
+
+#[bench]
+fn create_token_buffer(b: &mut Bencher) {
+ let tokens = get_tokens();
+ fn immediate_fail(_input: ParseStream) -> syn::Result<()> {
+ Err(syn::Error::new(Span::call_site(), ""))
+ }
+ b.iter(|| immediate_fail.parse2(tokens.clone()));
+}
+
+#[bench]
+fn parse_file(b: &mut Bencher) {
+ let tokens = get_tokens();
+ b.iter(|| syn::parse2::<syn::File>(tokens.clone()));
+}
diff --git a/vendor/syn/benches/rust.rs b/vendor/syn/benches/rust.rs
new file mode 100644
index 0000000..15536db
--- /dev/null
+++ b/vendor/syn/benches/rust.rs
@@ -0,0 +1,182 @@
+// $ cargo bench --features full,test --bench rust
+//
+// Syn only, useful for profiling:
+// $ RUSTFLAGS='--cfg syn_only' cargo build --release --features full,test --bench rust
+
+#![cfg_attr(not(syn_only), feature(rustc_private))]
+#![recursion_limit = "1024"]
+#![allow(
+ clippy::arc_with_non_send_sync,
+ clippy::cast_lossless,
+ clippy::let_underscore_untyped,
+ clippy::manual_let_else,
+ clippy::match_like_matches_macro,
+ clippy::uninlined_format_args,
+ clippy::unnecessary_wraps
+)]
+
+#[macro_use]
+#[path = "../tests/macros/mod.rs"]
+mod macros;
+
+#[allow(dead_code)]
+#[path = "../tests/repo/mod.rs"]
+mod repo;
+
+use std::fs;
+use std::time::{Duration, Instant};
+
+#[cfg(not(syn_only))]
+mod tokenstream_parse {
+ use proc_macro2::TokenStream;
+ use std::str::FromStr;
+
+ pub fn bench(content: &str) -> Result<(), ()> {
+ TokenStream::from_str(content).map(drop).map_err(drop)
+ }
+}
+
+mod syn_parse {
+ pub fn bench(content: &str) -> Result<(), ()> {
+ syn::parse_file(content).map(drop).map_err(drop)
+ }
+}
+
+#[cfg(not(syn_only))]
+mod librustc_parse {
+ extern crate rustc_data_structures;
+ extern crate rustc_driver;
+ extern crate rustc_error_messages;
+ extern crate rustc_errors;
+ extern crate rustc_parse;
+ extern crate rustc_session;
+ extern crate rustc_span;
+
+ use rustc_data_structures::sync::Lrc;
+ use rustc_error_messages::FluentBundle;
+ use rustc_errors::{emitter::Emitter, translation::Translate, DiagCtxt, Diagnostic};
+ use rustc_session::parse::ParseSess;
+ use rustc_span::source_map::{FilePathMapping, SourceMap};
+ use rustc_span::{edition::Edition, FileName};
+
+ pub fn bench(content: &str) -> Result<(), ()> {
+ struct SilentEmitter;
+
+ impl Emitter for SilentEmitter {
+ fn emit_diagnostic(&mut self, _diag: &Diagnostic) {}
+ fn source_map(&self) -> Option<&Lrc<SourceMap>> {
+ None
+ }
+ }
+
+ impl Translate for SilentEmitter {
+ fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
+ None
+ }
+ fn fallback_fluent_bundle(&self) -> &FluentBundle {
+ panic!("silent emitter attempted to translate a diagnostic");
+ }
+ }
+
+ rustc_span::create_session_if_not_set_then(Edition::Edition2018, |_| {
+ let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty()));
+ let emitter = Box::new(SilentEmitter);
+ let handler = DiagCtxt::with_emitter(emitter);
+ let sess = ParseSess::with_dcx(handler, source_map);
+ if let Err(diagnostic) = rustc_parse::parse_crate_from_source_str(
+ FileName::Custom("bench".to_owned()),
+ content.to_owned(),
+ &sess,
+ ) {
+ diagnostic.cancel();
+ return Err(());
+ };
+ Ok(())
+ })
+ }
+}
+
+#[cfg(not(syn_only))]
+mod read_from_disk {
+ pub fn bench(content: &str) -> Result<(), ()> {
+ let _ = content;
+ Ok(())
+ }
+}
+
+fn exec(mut codepath: impl FnMut(&str) -> Result<(), ()>) -> Duration {
+ let begin = Instant::now();
+ let mut success = 0;
+ let mut total = 0;
+
+ ["tests/rust/compiler", "tests/rust/library"]
+ .iter()
+ .flat_map(|dir| {
+ walkdir::WalkDir::new(dir)
+ .into_iter()
+ .filter_entry(repo::base_dir_filter)
+ })
+ .for_each(|entry| {
+ let entry = entry.unwrap();
+ let path = entry.path();
+ if path.is_dir() {
+ return;
+ }
+ let content = 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() {
+ repo::clone_rust();
+
+ macro_rules! testcases {
+ ($($(#[$cfg:meta])* $name:ident,)*) => {
+ [
+ $(
+ $(#[$cfg])*
+ (stringify!($name), $name::bench as fn(&str) -> Result<(), ()>),
+ )*
+ ]
+ };
+ }
+
+ #[cfg(not(syn_only))]
+ {
+ let mut lines = 0;
+ let mut files = 0;
+ exec(|content| {
+ lines += content.lines().count();
+ files += 1;
+ Ok(())
+ });
+ eprintln!("\n{} lines in {} files", lines, files);
+ }
+
+ for (name, f) in testcases!(
+ #[cfg(not(syn_only))]
+ read_from_disk,
+ #[cfg(not(syn_only))]
+ tokenstream_parse,
+ syn_parse,
+ #[cfg(not(syn_only))]
+ librustc_parse,
+ ) {
+ eprint!("{:20}", format!("{}:", name));
+ let elapsed = exec(f);
+ eprintln!(
+ "elapsed={}.{:03}s",
+ elapsed.as_secs(),
+ elapsed.subsec_millis(),
+ );
+ }
+ eprintln!();
+}