@@ -52,16 +52,25 @@ impl Drop for Scope {
52
52
/// Usage:
53
53
/// 1. Install gpref_tools (https://github.com/gperftools/gperftools), probably packaged with your Linux distro.
54
54
/// 2. Build with `cpu_profiler` feature.
55
- /// 3. Tun the code, the *raw* output would be in the `./out.profile` file.
55
+ /// 3. Run the code, the *raw* output would be in the `./out.profile` file.
56
56
/// 4. Install pprof for visualization (https://github.com/google/pprof).
57
57
/// 5. Bump sampling frequency to once per ms: `export CPUPROFILE_FREQUENCY=1000`
58
58
/// 6. Use something like `pprof -svg target/release/rust-analyzer ./out.profile` to see the results.
59
59
///
60
60
/// For example, here's how I run profiling on NixOS:
61
61
///
62
62
/// ```bash
63
- /// $ nix-shell -p gperftools --run \
64
- /// 'cargo run --release -p rust-analyzer -- parse < ~/projects/rustbench/parser.rs > /dev/null'
63
+ /// $ bat -p shell.nix
64
+ /// with import <nixpkgs> {};
65
+ /// mkShell {
66
+ /// buildInputs = [ gperftools ];
67
+ /// shellHook = ''
68
+ /// export LD_LIBRARY_PATH="${gperftools}/lib:"
69
+ /// '';
70
+ /// }
71
+ /// $ set -x CPUPROFILE_FREQUENCY 1000
72
+ /// $ nix-shell --run 'cargo test --release --package rust-analyzer --lib -- benchmarks::benchmark_integrated_highlighting --exact --nocapture'
73
+ /// $ pprof -svg target/release/deps/rust_analyzer-8739592dc93d63cb crates/rust-analyzer/out.profile > profile.svg
65
74
/// ```
66
75
///
67
76
/// See this diff for how to profile completions:
@@ -81,7 +90,9 @@ pub fn cpu_span() -> CpuSpan {
81
90
82
91
#[ cfg( not( feature = "cpu_profiler" ) ) ]
83
92
{
84
- eprintln ! ( "cpu_profiler feature is disabled" )
93
+ eprintln ! (
94
+ r#"cpu profiling is disabled, uncomment `default = [ "cpu_profiler" ]` in Cargo.toml to enable."#
95
+ )
85
96
}
86
97
87
98
CpuSpan { _private : ( ) }
@@ -91,7 +102,23 @@ impl Drop for CpuSpan {
91
102
fn drop ( & mut self ) {
92
103
#[ cfg( feature = "cpu_profiler" ) ]
93
104
{
94
- google_cpu_profiler:: stop ( )
105
+ google_cpu_profiler:: stop ( ) ;
106
+ let profile_data = std:: env:: current_dir ( ) . unwrap ( ) . join ( "out.profile" ) ;
107
+ eprintln ! ( "Profile data saved to:\n \n {}\n " , profile_data. display( ) ) ;
108
+ let mut cmd = std:: process:: Command :: new ( "pprof" ) ;
109
+ cmd. arg ( "-svg" ) . arg ( std:: env:: current_exe ( ) . unwrap ( ) ) . arg ( & profile_data) ;
110
+ let out = cmd. output ( ) ;
111
+
112
+ match out {
113
+ Ok ( out) if out. status . success ( ) => {
114
+ let svg = profile_data. with_extension ( "svg" ) ;
115
+ std:: fs:: write ( & svg, & out. stdout ) . unwrap ( ) ;
116
+ eprintln ! ( "Profile rendered to:\n \n {}\n " , svg. display( ) ) ;
117
+ }
118
+ _ => {
119
+ eprintln ! ( "Failed to run:\n \n {:?}\n " , cmd) ;
120
+ }
121
+ }
95
122
}
96
123
}
97
124
}
0 commit comments