Skip to content

Conversation

@motorailgun
Copy link
Contributor

@motorailgun motorailgun commented Jan 11, 2026

Close #16474.

What this PR addresses

As described in the issue above, cargo build --timings and cargo report timings each had its own metric collection logic. Because cargo report timings will supersede cargo build --timings, this PR try to remove redundant logics from core/compiler/timings/mod.rs.

Review points

  • I'm not sure if it's appropriate to modify logger for refactoring. However, logs emitted inside core/compiler/timings/mod.rs alone is not enough for prepare_context_from_iter() to properly replay the build so I think this is an appropriate way.

@rustbot rustbot added A-build-execution Area: anything dealing with executing the compiler A-rebuild-detection Area: rebuild detection and fingerprinting A-timings Area: timings Command-report labels Jan 11, 2026
@motorailgun motorailgun marked this pull request as ready for review January 12, 2026 15:21
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 12, 2026
@rustbot
Copy link
Collaborator

rustbot commented Jan 12, 2026

r? @weihanglo

rustbot has assigned @weihanglo.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@weihanglo
Copy link
Member

I'm not sure if it's appropriate to modify logger for refactoring. However, logs emitted inside core/compiler/timings/mod.rs alone is not enough for prepare_context_from_iter() to properly replay the build so I think this is an appropriate way.

The overall direction looks reasonable to me!

@motorailgun
Copy link
Contributor Author

Please see #16474 (comment), since they are already assigned to the parent issue, I have no objection to handing this PR over to @kurasaiteja (of course if they want).

if let Some(logger) = logger {
let root_unit_indexes: HashSet<_> =
root_units.iter().map(|unit| unit_to_index[&unit]).collect();
let root_unit_indexes: HashSet<_> =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should move into the if block at line 537.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right, thank you!

fn prepare_context(log: &Path, run_id: &RunId) -> CargoResult<RenderContext<'static>> {
let reader = BufReader::new(File::open(&log)?);

// FIXME: simply the types here once `cargo build --timings` support is dropped
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The --timings flag will stay forever. I don't think we'll drop it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't aware of that 👀

let reader = BufReader::new(File::open(&log)?);

// FIXME: simply the types here once `cargo build --timings` support is dropped
pub(crate) fn prepare_context_from_iter<T: Iterator<Item = LogMessage>>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits

  • Can just keep calling it prepare_context.
  • I would probable prefer where I: Iterator if that geenric is a bit too long


let (tx, rx) = mpsc::channel::<LogMessage>();
/// Logger for `-Zbuild-analysis`.
// fixme: simplify this struct once `cargo build --timings` support dropped
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto. It will be supported like forever.

// for legacy `cargo build --timings` flag
struct InMemoryLogger {
// using mutex to hide mutability
logs: Mutex<Vec<LogMessage>>,
Copy link
Member

@weihanglo weihanglo Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a Mutex here seems a little bit unfortunate. I think it is safe to use RefCell here to reduce the performance overhead, as timing appears to be on mainthread only.

cause,
});
}
let index = bcx.unit_to_index[unit];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we check if bcx.logger.i_senabled() first then construct log message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this point, I think it is better to leave logger as Option so that pre-existing check codes doesn't need to be changed. Will fix in such way!

Comment on lines 37 to 50
/// When Cargo started.
start: Instant,
/// A rendered string of when compilation started.
start_str: String,
/// A summary of the root units.
///
/// Tuples of `(package_description, target_descriptions)`.
root_targets: Vec<(String, Vec<String>)>,
/// The build profile.
profile: String,
/// Total number of fresh units.
total_fresh: u32,
/// Total number of dirty units.
total_dirty: u32,
/// A map from unit to index.
unit_to_index: HashMap<Unit, UnitIndex>,
/// Time tracking for each individual unit.
unit_times: Vec<UnitTime>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can all be dropped I feel like? The only thing we'll track here is CPU usage (and perhaps active)

elapsed,
unblocked,
});
self.unit_times.push(unit_time);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like the entire UnitTime struct could be removed. Did you see a reason keeping it?

Comment on lines 332 to 338
let timestamp = self.start_str.replace(&['-', ':'][..], "");
let timings_path = build_runner
.files()
.timings_dir()
.expect("artifact-dir was not locked");
paths::create_dir_all(&timings_path)?;
let filename = timings_path.join(format!("cargo-timing-{}.html", timestamp));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could probably change this file name to run-id name, just like how cargo report timings generate the report file name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-build-execution Area: anything dealing with executing the compiler A-rebuild-detection Area: rebuild detection and fingerprinting A-timings Area: timings Command-report S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reuse timing metric collection logic between --timings and -Zbuild-analysis

3 participants