aboutsummaryrefslogtreecommitdiff
path: root/crates/test_utils
diff options
context:
space:
mode:
Diffstat (limited to 'crates/test_utils')
-rw-r--r--crates/test_utils/Cargo.toml1
-rw-r--r--crates/test_utils/src/bench_fixture.rs42
-rw-r--r--crates/test_utils/src/fixture.rs11
-rw-r--r--crates/test_utils/src/lib.rs43
4 files changed, 87 insertions, 10 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..d775e2cc9
--- /dev/null
+++ b/crates/test_utils/src/bench_fixture.rs
@@ -0,0 +1,42 @@
1//! Generates large snippets of Rust code for usage in the benchmarks.
2
3use std::fs;
4
5use stdx::format_to;
6
7use crate::project_dir;
8
9pub fn big_struct() -> String {
10 let n = 1_000;
11
12 let mut buf = "pub struct RegisterBlock {".to_string();
13 for i in 0..n {
14 format_to!(buf, " /// Doc comment for {}.\n", i);
15 format_to!(buf, " pub s{}: S{},\n", i, i);
16 }
17 buf.push_str("}\n\n");
18 for i in 0..n {
19 format_to!(
20 buf,
21 "
22
23#[repr(transparent)]
24struct S{} {{
25 field: u32,
26}}",
27 i
28 );
29 }
30
31 buf
32}
33
34pub fn glorious_old_parser() -> String {
35 let path = project_dir().join("bench_data/glorious_old_parser");
36 fs::read_to_string(&path).unwrap()
37}
38
39pub fn numerous_macro_rules() -> String {
40 let path = project_dir().join("bench_data/numerous_macro_rules");
41 fs::read_to_string(&path).unwrap()
42}
diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs
index e40b61a94..e3f57f3b2 100644
--- a/crates/test_utils/src/fixture.rs
+++ b/crates/test_utils/src/fixture.rs
@@ -95,16 +95,7 @@ impl Fixture {
95 } 95 }
96 } 96 }
97 97
98 Fixture { 98 Fixture { path, text: String::new(), krate, deps, cfg_atoms, cfg_key_values, edition, env }
99 path,
100 text: String::new(),
101 krate: krate,
102 deps,
103 cfg_atoms,
104 cfg_key_values,
105 edition,
106 env,
107 }
108 } 99 }
109} 100}
110 101
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}