Rust windows profiling

I am working on writing some CPU-intensive code and trying to better understand how to profile a language like rust on Windows 11. So far, I have used tools such as Superluminal and WPR/WPA (windows performance).

Here are a few questions I have had so far:

  • How do I make sense of some of these? I am getting a bit lost diving through the call graphs, and my goal is to try and understand what is causing performance degradation.
  • Is there other tools available? My research into this showed a lot of the tools are for linux-based systems.
  • Why do so many paths lead to dead ends where no symbol was found? I have debug = true flag enabled for my build profile. Maybe this is common, I am new to systems-level language profiling.

Are there are good resources out there for this sort of thing to help me learn?

Attached image of the sort of UI I have been seeing so far. I generally just dive through these threads' call graphs until I see routines that take up abnormally large portions of the execution time, but can't tell if there is a better way to find/visualize these.

I was able to get useful profiles with Windows' CPU profiling. I opened them in Visual Studio and VS was able to find the source rs files and show perf info just fine.

I also wrote some code to automate collecting the profiles which may or may not be particularly useful to you. I haven't tested it again now but it worked for what I needed a couple months ago ¯\_(ツ)_/¯

Automate collecting perf info
 enum DiagnosticsError { 
 impl From<std::io::Error> for DiagnosticsError { 
     fn from(from: std::io::Error) -> Self { 
 impl From<ExitStatusError> for DiagnosticsError { 
     fn from(from: ExitStatusError) -> Self { 
 struct Diagnostics { 
     session: u8, 
     collector_path: Option<PathBuf>, 
 impl Diagnostics { 
     fn start( 
         collector_path: impl AsRef<Path>, 
         session: u8, 
         config: impl AsRef<Path>, 
     ) -> Result<Self, DiagnosticsError> { 
         let collector_path = collector_path.as_ref().to_owned(); 
             let session = session.to_string(); 
             let config = format!( 
             let attach = format!("/attach:{}", std::process::id()); 
                 .args(["start", &session, &config, &attach]) 
         Ok(Self { 
             collector_path: Some(collector_path), 
     fn stop(mut self, dest: impl AsRef<Path>) -> Result<(), DiagnosticsError> { 
     fn stop_inner(&mut self, dest: impl AsRef<Path>) -> Result<(), DiagnosticsError> { 
             let session = self.session.to_string(); 
             let output = format!("/output:{}", dest.as_ref().as_os_str().to_str().unwrap()); 
             let attach = format!("/attach:{}", std::process::id()); 
             .args(["stop", &session, &output, &attach]) 
 impl Drop for Diagnostics { 
     fn drop(&mut self) { 
         if self.collector_path.is_none() { 
         let dir = std::env::current_dir() 
             .join(format!("{}.diagsession", self.session)); 
             "WARNING: Stop was not called, stopping session with session name {}", 
 pub fn run_test() { 
     let diagnostics = Diagnostics::start(r"C:\Program Files\Microsoft Visual Studio\2022\Community\Team Tools\DiagnosticsHub\Collector", 1, r"AgentConfigs\CpuUsageHigh.json").unwrap(); 
     println!("Starting test"); 

     // Run profiled code here

     let mut dir = std::env::current_dir().unwrap().join(name); 
     println!("{:?}", dir); 
     println!("{:#?}", rx.recv().unwrap()); 

Thanks for the suggestion to use Visual Studio! I have been using primarily vscode so far while writing (mostly because I enjoyed the language support offered), and didn't think to go into Visual Studio. I was able to get more readable results with better visualizations for where my program spent most of its time through its Performance Profiler.

And I appreciate you passing the script along. I will try it out if I hit another wall here.

1 Like

There's another situation where Visual Studio shines, albeit a pretty niche one: It works pretty good with Visual Studio's remote debugging facilities. This comes in handy if you, for instance, need to debug a Rust service during early boot.

Visual Studio is a handy tool for Rust-on-Windows developers to have in their toolbox, imho.