Introduce a `ZED_MEASUREMENTS` env var and use it to measure frame time

Antonio Scandurra created

Change summary

crates/gpui/src/window.rs |  6 ++++--
crates/util/src/util.rs   | 28 ++++++++++++++++++++++++----
script/histogram          |  9 +++++++++
3 files changed, 37 insertions(+), 6 deletions(-)

Detailed changes

crates/gpui/src/window.rs ๐Ÿ”—

@@ -34,7 +34,7 @@ use std::{
         Arc,
     },
 };
-use util::ResultExt;
+use util::{measure, ResultExt};
 
 mod element_cx;
 pub use element_cx::*;
@@ -310,7 +310,9 @@ impl Window {
         platform_window.on_request_frame(Box::new({
             let mut cx = cx.to_async();
             move || {
-                handle.update(&mut cx, |_, cx| cx.draw()).log_err();
+                measure("frame duration", || {
+                    handle.update(&mut cx, |_, cx| cx.draw()).log_err();
+                })
             }
         }));
         platform_window.on_resize(Box::new({

crates/util/src/util.rs ๐Ÿ”—

@@ -7,19 +7,21 @@ pub mod paths;
 #[cfg(any(test, feature = "test-support"))]
 pub mod test;
 
+pub use backtrace::Backtrace;
+use futures::Future;
+use lazy_static::lazy_static;
+use rand::{seq::SliceRandom, Rng};
 use std::{
     borrow::Cow,
     cmp::{self, Ordering},
+    env,
     ops::{AddAssign, Range, RangeInclusive},
     panic::Location,
     pin::Pin,
     task::{Context, Poll},
+    time::Instant,
 };
 
-pub use backtrace::Backtrace;
-use futures::Future;
-use rand::{seq::SliceRandom, Rng};
-
 pub use take_until::*;
 
 #[macro_export]
@@ -133,6 +135,24 @@ pub fn merge_non_null_json_value_into(source: serde_json::Value, target: &mut se
     }
 }
 
+pub fn measure<R>(label: &str, f: impl FnOnce() -> R) -> R {
+    lazy_static! {
+        pub static ref ZED_MEASUREMENTS: bool = env::var("ZED_MEASUREMENTS")
+            .map(|measurements| measurements == "1" || measurements == "true")
+            .unwrap_or(false);
+    }
+
+    if *ZED_MEASUREMENTS {
+        let start = Instant::now();
+        let result = f();
+        let elapsed = start.elapsed();
+        eprintln!("{}: {:?}", label, elapsed);
+        result
+    } else {
+        f()
+    }
+}
+
 pub trait ResultExt<E> {
     type Ok;
 

script/histogram ๐Ÿ”—

@@ -1,5 +1,14 @@
 #!/usr/bin/env python3
 
+# Required dependencies for this script:
+#
+# pandas: For data manipulation and analysis.
+# matplotlib: For creating static, interactive, and animated visualizations in Python.
+# seaborn: For making statistical graphics in Python, based on matplotlib.
+
+# To install these dependencies, use the following pip command:
+# pip install pandas matplotlib seaborn
+
 # This script is designed to parse log files for performance measurements and create histograms of these measurements.
 # It expects log files to contain lines with measurements in the format "measurement: timeunit" where timeunit can be in milliseconds (ms) or microseconds (ยตs).
 # Lines that do not contain a colon ':' are skipped.