diff options
Diffstat (limited to 'crates/test_utils')
-rw-r--r-- | crates/test_utils/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/test_utils/src/bench_fixture.rs | 42 | ||||
-rw-r--r-- | crates/test_utils/src/fixture.rs | 11 | ||||
-rw-r--r-- | crates/test_utils/src/lib.rs | 43 |
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" | |||
17 | rustc-hash = "1.1.0" | 17 | rustc-hash = "1.1.0" |
18 | 18 | ||
19 | stdx = { path = "../stdx", version = "0.0.0" } | 19 | stdx = { path = "../stdx", version = "0.0.0" } |
20 | profile = { 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 | |||
3 | use std::fs; | ||
4 | |||
5 | use stdx::format_to; | ||
6 | |||
7 | use crate::project_dir; | ||
8 | |||
9 | pub 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)] | ||
24 | struct S{} {{ | ||
25 | field: u32, | ||
26 | }}", | ||
27 | i | ||
28 | ); | ||
29 | } | ||
30 | |||
31 | buf | ||
32 | } | ||
33 | |||
34 | pub 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 | |||
39 | pub 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] |
10 | pub mod mark; | 10 | pub mod mark; |
11 | pub mod bench_fixture; | ||
11 | mod fixture; | 12 | mod fixture; |
12 | 13 | ||
13 | use std::{ | 14 | use std::{ |
@@ -16,6 +17,7 @@ use std::{ | |||
16 | path::PathBuf, | 17 | path::PathBuf, |
17 | }; | 18 | }; |
18 | 19 | ||
20 | use profile::StopWatch; | ||
19 | use serde_json::Value; | 21 | use serde_json::Value; |
20 | use stdx::lines_with_ends; | 22 | use stdx::lines_with_ends; |
21 | use text_size::{TextRange, TextSize}; | 23 | use 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. | ||
438 | pub 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 | } | ||