diff options
author | Aleksey Kladov <[email protected]> | 2019-06-16 17:19:38 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-06-16 17:45:05 +0100 |
commit | 6314e62cfb06ea7bbe5f530f2824010be0ffa4c7 (patch) | |
tree | 022742121ea273b6e90f6fbfa342660f46e9f68e /crates/ra_cli/src/main.rs | |
parent | b81caed43f1886024ededad41a1baa8a03f1d2f4 (diff) |
add analysis-bench to benchmark incremental analysis
Can be used like this:
```
$ cargo run --release -p ra_cli -- \
analysis-bench ../chalk/ \
--complete ../chalk/chalk-engine/src/logic.rs:94:0
loading: 225.970093ms
from scratch: 8.492373325s
no change: 445.265µs
trivial change: 95.631242ms
```
Or like this:
```
$ cargo run --release -p ra_cli -- \
analysis-bench ../chalk/ \
--highlight ../chalk/chalk-engine/src/logic.rs
loading: 209.873484ms
from scratch: 9.504916942s
no change: 7.731119ms
trivial change: 124.984039ms
```
"from scratch" includes initial analysis of the relevant bits of the
project
"no change" just asks the same question for the second time. It
measures overhead on assembling the answer outside of salsa.
"trivial change" doesn't do an actual salsa change, it just advances
the revision. This test how fast is salsa at validating things.
Diffstat (limited to 'crates/ra_cli/src/main.rs')
-rw-r--r-- | crates/ra_cli/src/main.rs | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index 1db98aec1..5adf8b096 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs | |||
@@ -1,4 +1,5 @@ | |||
1 | mod analysis_stats; | 1 | mod analysis_stats; |
2 | mod analysis_bench; | ||
2 | 3 | ||
3 | use std::{io::Read, error::Error}; | 4 | use std::{io::Read, error::Error}; |
4 | 5 | ||
@@ -26,6 +27,27 @@ fn main() -> Result<()> { | |||
26 | .arg(Arg::with_name("only").short("o").takes_value(true)) | 27 | .arg(Arg::with_name("only").short("o").takes_value(true)) |
27 | .arg(Arg::with_name("path")), | 28 | .arg(Arg::with_name("path")), |
28 | ) | 29 | ) |
30 | .subcommand( | ||
31 | SubCommand::with_name("analysis-bench") | ||
32 | .arg(Arg::with_name("verbose").short("v").long("verbose")) | ||
33 | .arg( | ||
34 | Arg::with_name("highlight") | ||
35 | .long("highlight") | ||
36 | .takes_value(true) | ||
37 | .conflicts_with("complete") | ||
38 | .value_name("PATH") | ||
39 | .help("highlight this file"), | ||
40 | ) | ||
41 | .arg( | ||
42 | Arg::with_name("complete") | ||
43 | .long("complete") | ||
44 | .takes_value(true) | ||
45 | .conflicts_with("highlight") | ||
46 | .value_name("PATH:LINE:COLUMN") | ||
47 | .help("compute completions at this location"), | ||
48 | ) | ||
49 | .arg(Arg::with_name("path").value_name("PATH").help("project to analyze")), | ||
50 | ) | ||
29 | .get_matches(); | 51 | .get_matches(); |
30 | match matches.subcommand() { | 52 | match matches.subcommand() { |
31 | ("parse", Some(matches)) => { | 53 | ("parse", Some(matches)) => { |
@@ -51,7 +73,25 @@ fn main() -> Result<()> { | |||
51 | let verbose = matches.is_present("verbose"); | 73 | let verbose = matches.is_present("verbose"); |
52 | let path = matches.value_of("path").unwrap_or(""); | 74 | let path = matches.value_of("path").unwrap_or(""); |
53 | let only = matches.value_of("only"); | 75 | let only = matches.value_of("only"); |
54 | analysis_stats::run(verbose, path, only)?; | 76 | analysis_stats::run(verbose, path.as_ref(), only)?; |
77 | } | ||
78 | ("analysis-bench", Some(matches)) => { | ||
79 | let verbose = matches.is_present("verbose"); | ||
80 | let path = matches.value_of("path").unwrap_or(""); | ||
81 | let op = if let Some(path) = matches.value_of("highlight") { | ||
82 | analysis_bench::Op::Highlight { path: path.into() } | ||
83 | } else if let Some(path_line_col) = matches.value_of("complete") { | ||
84 | let (path_line, column) = rsplit_at_char(path_line_col, ':')?; | ||
85 | let (path, line) = rsplit_at_char(path_line, ':')?; | ||
86 | analysis_bench::Op::Complete { | ||
87 | path: path.into(), | ||
88 | line: line.parse()?, | ||
89 | column: column.parse()?, | ||
90 | } | ||
91 | } else { | ||
92 | panic!("either --highlight or --complete must be set") | ||
93 | }; | ||
94 | analysis_bench::run(verbose, path.as_ref(), op)?; | ||
55 | } | 95 | } |
56 | _ => unreachable!(), | 96 | _ => unreachable!(), |
57 | } | 97 | } |
@@ -68,3 +108,8 @@ fn read_stdin() -> Result<String> { | |||
68 | std::io::stdin().read_to_string(&mut buff)?; | 108 | std::io::stdin().read_to_string(&mut buff)?; |
69 | Ok(buff) | 109 | Ok(buff) |
70 | } | 110 | } |
111 | |||
112 | fn rsplit_at_char(s: &str, c: char) -> Result<(&str, &str)> { | ||
113 | let idx = s.rfind(":").ok_or_else(|| format!("no `{}` in {}", c, s))?; | ||
114 | Ok((&s[..idx], &s[idx + 1..])) | ||
115 | } | ||