Skip to content

Commit

Permalink
test: add benchmarks to existing lsp tests
Browse files Browse the repository at this point in the history
  • Loading branch information
He1pa committed Aug 29, 2023
1 parent 34b7fb6 commit 22fe768
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 22 deletions.
38 changes: 24 additions & 14 deletions kclvm/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions kclvm/tools/src/LSP/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ salsa = { version = "0.16.1", default-features = false }
serde_json = { version = "1.0", default-features = false }
parking_lot = { version = "0.12.0", default-features = false }
rustc-hash = { version = "1.1.0", default-features = false }
proc_macro_crate = {path = "./proc_macro_crate"}
14 changes: 14 additions & 0 deletions kclvm/tools/src/LSP/proc_macro_crate/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "proc_macro_crate"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
proc-macro = true

[dependencies]
proc-macro2 = "1.0.7"
quote = "1"
syn = { version = "2.0.29", features = ["full","extra-traits"] }
32 changes: 32 additions & 0 deletions kclvm/tools/src/LSP/proc_macro_crate/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, ItemFn};

#[proc_macro_attribute]
pub fn bench_test(_attr: TokenStream, item: TokenStream) -> TokenStream {
let mut input_fn = parse_macro_input!(item as ItemFn);

let fn_name = &input_fn.sig.ident;
let fn_body = &input_fn.block;

let timing_code = quote! {
{
let start_time = std::time::Instant::now();
let result = #fn_body;
let end_time = std::time::Instant::now();
let time = (end_time - start_time).as_micros();
println!("{} took {} μs", stringify!(#fn_name), (end_time - start_time).as_micros());
// 200 ms
assert!(time < 200000, "Bench mark test failed");
result
}
};

input_fn.block = Box::new(syn::parse2(timing_code).unwrap());

let output = quote! {
#input_fn
};

output.into()
}
1 change: 1 addition & 0 deletions kclvm/tools/src/LSP/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ mod goto_def;
mod hover;
mod quick_fix;
mod request;
mod test_utils;
1 change: 1 addition & 0 deletions kclvm/tools/src/LSP/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod notification;
mod quick_fix;
mod request;
mod state;
mod test_utils;
mod to_lsp;
mod util;

Expand Down
78 changes: 78 additions & 0 deletions kclvm/tools/src/LSP/src/test_utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use std::{
fmt,
time::{Duration, Instant},
};

pub struct StopWatch {
time: Instant,
}

pub struct StopWatchSpan {
pub time: Duration,
}

impl StopWatch {
pub fn start() -> StopWatch {
let time = Instant::now();
StopWatch { time }
}

pub fn elapsed(&mut self) -> StopWatchSpan {
let time = self.time.elapsed();

StopWatchSpan { time }
}
}

impl fmt::Display for StopWatchSpan {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:.2?}", self.time)?;
Ok(())
}
}

/// Utility for writing benchmark tests.
///
/// If you need to benchmark the entire test, you can directly add the macro `#[bench_test]` like this:
/// ```
/// #[test]
/// #[bench_test]
/// fn benchmark_foo() {
/// actual_work(analysis)
/// }
/// ```
///
/// If you need to skip some preparation stages and only test some parts of test, you can use the `bench()` method.
/// A benchmark test looks like this:
///
/// ```
/// #[test]
/// fn benchmark_foo() {
/// let data = bench_fixture::some_fixture();
/// let analysis = some_setup();
///
/// {
/// let _b = bench("foo");
/// actual_work(analysis)
/// };
/// }
/// ```
///
///
pub fn bench(label: &'static str) -> impl Drop {
struct Bencher {
sw: StopWatch,
label: &'static str,
}

impl Drop for Bencher {
fn drop(&mut self) {
eprintln!("{}: {}", self.label, self.sw.elapsed());
}
}

Bencher {
sw: StopWatch::start(),
label,
}
}
Loading

0 comments on commit 22fe768

Please sign in to comment.