react_compiler/timing.rs
1// Copyright (c) Meta Platforms, Inc. and affiliates.
2//
3// This source code is licensed under the MIT license found in the
4// LICENSE file in the root directory of this source tree.
5
6//! Simple timing accumulator for profiling compiler passes.
7//!
8//! Uses `std::time::Instant` unconditionally (cheap when not storing results).
9//! Controlled by the `__profiling` flag in plugin options.
10
11use serde::Serialize;
12use std::time::{Duration, Instant};
13
14/// A single timing entry recording how long a named phase took.
15#[derive(Debug, Clone, Serialize)]
16pub struct TimingEntry {
17 pub name: String,
18 pub duration_us: u64,
19}
20
21/// Accumulates timing data for compiler passes.
22pub struct TimingData {
23 enabled: bool,
24 entries: Vec<(String, Duration)>,
25 current_name: Option<String>,
26 current_start: Option<Instant>,
27}
28
29impl TimingData {
30 /// Create a new TimingData. If `enabled` is false, all operations are no-ops.
31 pub fn new(enabled: bool) -> Self {
32 Self {
33 enabled,
34 entries: Vec::new(),
35 current_name: None,
36 current_start: None,
37 }
38 }
39
40 /// Start timing a named phase. Stops any currently running phase first.
41 pub fn start(&mut self, name: &str) {
42 if !self.enabled {
43 return;
44 }
45 // Stop any currently running phase
46 if self.current_start.is_some() {
47 self.stop();
48 }
49 self.current_name = Some(name.to_string());
50 self.current_start = Some(Instant::now());
51 }
52
53 /// Stop the currently running phase and record its duration.
54 pub fn stop(&mut self) {
55 if !self.enabled {
56 return;
57 }
58 if let (Some(name), Some(start)) = (self.current_name.take(), self.current_start.take()) {
59 self.entries.push((name, start.elapsed()));
60 }
61 }
62
63 /// Consume this TimingData and return the collected entries.
64 pub fn into_entries(mut self) -> Vec<TimingEntry> {
65 // Stop any still-running phase
66 self.stop();
67 self.entries
68 .into_iter()
69 .map(|(name, duration)| TimingEntry {
70 name,
71 duration_us: duration.as_micros() as u64,
72 })
73 .collect()
74 }
75}