惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Exploit Database - CXSecurity.com
F
Fortinet All Blogs
U
Unit 42
F
Full Disclosure
雷峰网
雷峰网
博客园 - 司徒正美
云风的 BLOG
云风的 BLOG
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
罗磊的独立博客
D
DataBreaches.Net
C
Check Point Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
O
OpenAI News
C
CXSECURITY Database RSS Feed - CXSecurity.com
aimingoo的专栏
aimingoo的专栏
S
Security @ Cisco Blogs
大猫的无限游戏
大猫的无限游戏
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
SegmentFault 最新的问题
NISL@THU
NISL@THU
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Hacker News
The Hacker News
Webroot Blog
Webroot Blog
Security Latest
Security Latest
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Google DeepMind News
Google DeepMind News
酷 壳 – CoolShell
酷 壳 – CoolShell
N
News | PayPal Newsroom
P
Proofpoint News Feed
B
Blog RSS Feed
MongoDB | Blog
MongoDB | Blog
C
Cybersecurity and Infrastructure Security Agency CISA
N
News and Events Feed by Topic
Google Online Security Blog
Google Online Security Blog
H
Help Net Security
Spread Privacy
Spread Privacy
T
Threat Research - Cisco Blogs
GbyAI
GbyAI
I
Intezer
Application and Cybersecurity Blog
Application and Cybersecurity Blog
M
MIT News - Artificial intelligence
Vercel News
Vercel News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
IT之家
IT之家
MyScale Blog
MyScale Blog
腾讯CDC

Rust Blog

Security Advisory for Cargo (CVE-2026-5223) | Rust Blog Security Advisory for Cargo (CVE-2026-5222) | Rust Blog Project goals update — April 2026 (end of 2025H2) | Rust Blog Rust is participating in Outreachy | Rust Blog Raising the baseline for the `nvptx64-nvidia-cuda` target | Rust Blog Announcing Google Summer of Code 2026 selected projects | Rust Blog Announcing Rust 1.95.0 | Rust Blog docs.rs: building fewer targets by default | Rust Blog Changes to WebAssembly targets and handling undefined symbols | Rust Blog Announcing Rust 1.94.1 | Rust Blog Security advisory for Cargo | Rust Blog What we heard about Rust's challenges | Rust Blog Call for Testing: Build Dir Layout v2 | Rust Blog Announcing rustup 1.29.0 | Rust Blog Announcing Rust 1.94.0 | Rust Blog 2025 State of Rust Survey Results | Rust Blog Rust debugging survey 2026 | Rust Blog Update on the October 15, 2018 incident on crates.io Announcing Rust 1.29.2 Announcing Rust 1.29 Announcing Rust 1.28 What is Rust 2018? Announcing Rust 1.27.2 Announcing Rust 1.27.1 Security Advisory for rustdoc Announcing Rust 1.27 Announcing Rust 1.26.2 Announcing Rust 1.26.1 Rust turns three Announcing Rust 1.26 The Rust Team All Hands in Berlin: a Recap Increasing Rust’s Reach 2018 Announcing Rust 1.25 Rust's 2018 roadmap Announcing Rust 1.24.1 Announcing Rust 1.24 The 2018 Rust Event Lineup Announcing Rust 1.23 New Year's Rust: A Call for Community Blogposts Rust in 2017: what we achieved Announcing Rust 1.22 (and 1.22.1) Fearless Concurrency in Firefox Quantum Announcing Rust 1.21 impl Future for Rust Rust 2017 Survey Results Announcing Rust 1.20 Announcing Rust 1.19 The 2017 Rust Conference Lineup Rust's 2017 roadmap, six months in Increasing Rust’s Reach Announcing Rust 1.18 Two years of Rust The Rust Libz Blitz Launching the 2017 State of Rust Survey Announcing Rust 1.17 Announcing Rust 1.16 Rust's language ergonomics initiative Announcing Rust 1.15.1 Rust's 2017 roadmap Announcing Rust 1.15 Announcing Rust 1.14 Announcing the First Underhanded Rust Contest Announcing Rust 1.13 Announcing Rust 1.12.1 Announcing Rust 1.12 Incremental Compilation Announcing Rust 1.11 Shape of errors to come The 2016 Rust Conference Lineup Announcing Rust 1.10 State of Rust Survey 2016 Announcing Rust 1.9 One year of Rust Taking Rust everywhere with rustup Launching the 2016 State of Rust Survey Cargo: predictable dependency management Introducing MIR Announcing Rust 1.8 Announcing Rust 1.7 Announcing Rust 1.6 Announcing Rust 1.5 Announcing Rust 1.4 Announcing Rust 1.3 Rust in 2016 Announcing Rust 1.2 Rust 1.1 stable, the Community Subteam, and RustCamp Announcing Rust 1.0 Abstraction without overhead: traits in Rust Rust Once, Run Everywhere Mixing matching, mutation, and moves in Rust Fearless Concurrency with Rust Announcing Rust 1.0 Beta Announcing Rust 1.0.0.alpha.2 Rust 1.0: status report and final timeline Announcing Rust 1.0 Alpha Rust 1.0: Scheduling the trains Yehuda Katz and Steve Klabnik are joining the Rust Core Team Cargo: Rust's community crate host Stability as a Deliverable Road to Rust 1.0
Intro to rustc's self profiler | Inside Rust Blog
Wesley Wiser on behalf of the self-profile working group · 2020-02-25 · via Rust Blog

Over the last year, the Self-Profile Working Group has been building tools to profile rustc because we often hear requests to know where compilation time is being spent. This is useful when optimizing the compiler, one of the Compiler Team's ongoing efforts to improve compile times, but it's also useful to users who want to refactor their crate so that it will compile faster. We've been working on a new feature that will help with that and this blog post gives a preview of how it works. Be warned, though: it is still experimental and we expect the interface to change over time. The Rust Unstable Book has documentation for this feature and we'll keep that up to date so you can always find the latest instructions there.

In this post, we'll look at the tools currently available and use them to profile rustc while it compiles an example crate.

Setup

First, we'll install the tools we're going to use from the measureme repository to analyze self-profile trace data.

$ cargo install --git https://github.com/rust-lang/measureme crox flamegraph summarize

Now that we have our tools, let's download an example crate to profile its build.

$ cd ..
$ git clone https://github.com/rust-lang/regex.git
$ cd regex

We'll need to use a recent nightly compiler to get access to unstable -Z flags.

$ rustup override set nightly

If you haven't installed a nightly compiler before, this will download the nightly compiler for you. If you have, then update it to make sure you're on a recent version.

$ rustup update nightly

Profiling the compiler

Now we can build it and tell rustc to profile the build of the regex crate. This will cause three new files to be created in the working directory which contain the profiling data.

$ cargo rustc -- -Zself-profile
$ ls
CHANGELOG.md        LICENSE-APACHE       UNICODE.md              regex-17088.string_data       regex-syntax         target
Cargo.lock          LICENSE-MIT          bench                   regex-17088.string_index      rustfmt.toml         test
Cargo.toml          PERFORMANCE.md       examples                regex-capi                    scripts              tests
HACKING.md          README.md            regex-17088.events      regex-debug                   src

The new files follow the format {crate name}-{rustc process id}.{events,string_data,string_index}.

We'll use each of the three main tools to analyze the profiling data:

summarize

As its name suggests, this tool summarizes the data found in the trace files. Additionally, summarize can also show a "diff" between two trace files but we won't be using this mode.

Let's run the tool, passing just the file name (but not the extension) for the trace:

$ summarize summarize regex-17088
+-----------------------------------------------+-----------+-----------------+----------+------------+
| Item                                          | Self time | % of total time | Time     | Item count |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| LLVM_module_codegen_emit_obj                  | 4.89s     | 42.752          | 4.89s    | 159        |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| codegen_module                                | 1.25s     | 10.967          | 1.37s    | 159        |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| LLVM_module_optimize_module_passes            | 1.15s     | 10.022          | 1.15s    | 159        |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| LLVM_module_codegen_make_bitcode              | 786.56ms  | 6.875           | 960.73ms | 159        |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| typeck_tables_of                              | 565.18ms  | 4.940           | 689.39ms | 848        |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| LLVM_module_codegen                           | 408.01ms  | 3.566           | 6.26s    | 159        |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| mir_borrowck                                  | 224.03ms  | 1.958           | 543.33ms | 848        |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| LLVM_module_codegen_emit_compressed_bitcode   | 174.17ms  | 1.522           | 174.17ms | 159        |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| optimized_mir                                 | 157.91ms  | 1.380           | 205.29ms | 1996       |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| evaluate_obligation                           | 146.50ms  | 1.281           | 184.17ms | 8304       |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| codegen_crate                                 | 139.48ms  | 1.219           | 1.58s    | 1          |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| mir_built                                     | 123.88ms  | 1.083           | 168.01ms | 848        |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| metadata_decode_entry                         | 88.36ms   | 0.772           | 117.77ms | 55642      |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| incr_comp_copy_cgu_workproducts               | 64.21ms   | 0.561           | 64.21ms  | 1          |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| monomorphization_collector_graph_walk         | 54.11ms   | 0.473           | 344.00ms | 1          |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| link_rlib                                     | 43.21ms   | 0.378           | 43.21ms  | 1          |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| check_impl_item_well_formed                   | 41.36ms   | 0.362           | 77.14ms  | 736        |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| codegen_fulfill_obligation                    | 40.36ms   | 0.353           | 51.56ms  | 1759       |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| expand_crate                                  | 37.24ms   | 0.326           | 48.52ms  | 1          |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| symbol_name                                   | 36.31ms   | 0.317           | 39.06ms  | 5513       |
+-----------------------------------------------+-----------+-----------------+----------+------------+
| free_global_ctxt                              | 34.34ms   | 0.300           | 34.34ms  | 1          |
+-----------------------------------------------+-----------+-----------------+----------+------------+
...
Total cpu time: 11.440758871s

The output is sorted by the self time (time spent in the query or activity but not other queries or activities called by itself). As you can see, most of the compilation time is spent in LLVM generating the binary code for the executable.

flamegraph

As you may have guessed, flamegraph will produce a flame graph of the profiling data. To run the tool, we'll pass just the filename without a file extension like we did for summarize:

$ flamegraph regex-17088

This will create a file called rustc.svg in the working directory:

Image of flamegraph output

Click here to try the interactive svg.

crox

This tool processes self-profiling data into the JSON format that the Chromium profiler understands. You can use it to create a graphical timeline showing exactly when various traced events occurred.

In this section, we'll cover a few different modes crox can run in such as profiling an entire crate compilation including dependencies and filtering out small events. Let's get started with the basics!

Basic usage

To run the tool, we'll just pass the filename without a file extension like we've done before:

$ crox regex-17088

This creates a file called chrome_profiler.json in the working directory. To open it, we'll use the regular Chromium performance tools you might already be familiar with:

  1. Open Chrome
  2. Open the Developer Tools console by pressing Ctrl + Shift + i (Windows/Linux) or Cmd + Option + i (macOS)
  3. Click the Performance tab at the top of the console.
  4. Click the "Load profile" button which looks like an arrow pointing up.
  5. Select the chrome_profiler.json file we created.

You should now see something similar to this:

Image of chrome profiler

You can use the scroll wheel on a mouse or the appropriate gesture on a touchpad to zoom in or out of the timeline.

Filtering short events

If the chrome_profiler.json file gets too large, the normal Chromium performance tools have issues opening the file. One easy way to deal with this is to tell crox to remove events shorter than a chosen duration:

$ crox --minimum-duration 2 regex-17088

Filtering out events less than 2 microseconds shrinks our chrome_profiler.js file from 27mb to 11mb.

Capturing event arguments

The self-profiler can be configured to record event arguments during compilation. For example, queries will include their query key. This functionality is turned off by default because it increases the self-profiler overhead.

To turn this feature on, we'll need to record a new compilation, passing an additional argument to rustc:

$ cargo clean
$ cargo rustc -- -Zself-profile -Zself-profile-events=default,args

And then process the new output files:

$ crox regex-23649

Now in the Chromium profiler, if you click on a node, you can see additional data about many of the events at the bottom of the screen:

Image of Chrome profiler details

Which shows this optimized_mir query was processing the regex::compile::{{impl}}::new function body.

Profiling an entire crate graph

By using the RUSTFLAGS environment variable, we can profile every rustc invocation, not just the final crate's. crox can then combine all of the profiles together into one output file. Since this will create a lot of files, we'll tell rustc to create a folder to put all the traces in.

$ rm regex-17088.* regex-23649.* # clean up the old trace files since we're done with them
$ cargo clean
$ RUSTFLAGS="-Zself-profile=$(pwd)/profiles -Zself-profile-events=default,args" cargo build

This creates quite a few trace files in the working directory. Now, we'll tell crox to combine all of the trace files in the current directory together:

$ crox --dir profiles

Opening this file shows all of the crates compiled:

Image of Chrome profiler with all crates

Clicking on a crate will expand it to show the threads and event data inside it:

Image of Chrome profiler with a crate expanded

Thanks for reading!

We've been using these tools extensively ourselves over the last few months and they've helped us tremendously in understanding where the compiler spends its time. In the future we'll be adding more features and we'll work on making the tooling easier to use. If you have questions or would like to get involved with the Self-Profile Working Group, please check out the measureme repository or stop by our Zulip stream.