aboutsummaryrefslogtreecommitdiff
path: root/crates/test_utils
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-02-09 16:29:40 +0000
committerAleksey Kladov <[email protected]>2021-02-09 17:25:39 +0000
commit4b1279d0b160d98c1429ca1a52b37aa7a0af5775 (patch)
tree8b71d80a070120904b76fca78d8db45b3000e9b3 /crates/test_utils
parent9ea2c96ddd0ad8c8898f1c65667a57a78ba2218c (diff)
Infra for "unit" benchmarking
Diffstat (limited to 'crates/test_utils')
-rw-r--r--crates/test_utils/Cargo.toml1
-rw-r--r--crates/test_utils/src/bench_fixture.rs28
-rw-r--r--crates/test_utils/src/lib.rs43
3 files changed, 72 insertions, 0 deletions
diff --git a/crates/test_utils/Cargo.toml b/crates/test_utils/Cargo.toml
index 06341f003..2a65000b8 100644
--- a/crates/test_utils/Cargo.toml
+++ b/crates/test_utils/Cargo.toml
@@ -17,3 +17,4 @@ serde_json = "1.0.48"
17rustc-hash = "1.1.0" 17rustc-hash = "1.1.0"
18 18
19stdx = { path = "../stdx", version = "0.0.0" } 19stdx = { path = "../stdx", version = "0.0.0" }
20profile = { path = "../profile", version = "0.0.0" }
diff --git a/crates/test_utils/src/bench_fixture.rs b/crates/test_utils/src/bench_fixture.rs
new file mode 100644
index 000000000..41fcca635
--- /dev/null
+++ b/crates/test_utils/src/bench_fixture.rs
@@ -0,0 +1,28 @@
1//! Generates large snippets of Rust code for usage in the benchmarks.
2
3use stdx::format_to;
4
5pub fn big_struct() -> String {
6 let n = 1_000;
7
8 let mut buf = "pub struct RegisterBlock {".to_string();
9 for i in 0..n {
10 format_to!(buf, " /// Doc comment for {}.\n", i);
11 format_to!(buf, " pub s{}: S{},\n", i, i);
12 }
13 buf.push_str("}\n\n");
14 for i in 0..n {
15 format_to!(
16 buf,
17 "
18
19#[repr(transparent)]
20struct S{} {{
21 field: u32,
22}}",
23 i
24 );
25 }
26
27 buf
28}
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs
index e19d2ad61..5be4a64fc 100644
--- a/crates/test_utils/src/lib.rs
+++ b/crates/test_utils/src/lib.rs
@@ -8,6 +8,7 @@
8 8
9#[macro_use] 9#[macro_use]
10pub mod mark; 10pub mod mark;
11pub mod bench_fixture;
11mod fixture; 12mod fixture;
12 13
13use std::{ 14use std::{
@@ -16,6 +17,7 @@ use std::{
16 path::PathBuf, 17 path::PathBuf,
17}; 18};
18 19
20use profile::StopWatch;
19use serde_json::Value; 21use serde_json::Value;
20use stdx::lines_with_ends; 22use stdx::lines_with_ends;
21use text_size::{TextRange, TextSize}; 23use text_size::{TextRange, TextSize};
@@ -406,3 +408,44 @@ pub fn format_diff(chunks: Vec<dissimilar::Chunk>) -> String {
406 } 408 }
407 buf 409 buf
408} 410}
411
412/// Utility for writing benchmark tests.
413///
414/// A benchmark test looks like this:
415///
416/// ```
417/// #[test]
418/// fn benchmark_foo() {
419/// if skip_slow_tests() { return; }
420///
421/// let data = bench_fixture::some_fixture();
422/// let analysis = some_setup();
423///
424/// let hash = {
425/// let _b = bench("foo");
426/// actual_work(analysis)
427/// };
428/// assert_eq!(hash, 92);
429/// }
430/// ```
431///
432/// * We skip benchmarks by default, to save time.
433/// Ideal benchmark time is 800 -- 1500 ms in debug.
434/// * We don't count preparation as part of the benchmark
435/// * The benchmark itself returns some kind of numeric hash.
436/// The hash is used as a sanity check that some code is actually run.
437/// Otherwise, it's too easy to win the benchmark by just doing nothing.
438pub fn bench(label: &'static str) -> impl Drop {
439 struct Bencher {
440 sw: StopWatch,
441 label: &'static str,
442 }
443
444 impl Drop for Bencher {
445 fn drop(&mut self) {
446 eprintln!("{}: {}", self.label, self.sw.elapsed())
447 }
448 }
449
450 Bencher { sw: StopWatch::start(), label }
451}