Detailed changes
@@ -7112,6 +7112,7 @@ dependencies = [
"sum_tree",
"taffy",
"thiserror 2.0.12",
+ "tracy-client",
"tracy-client-sys",
"unicode-segmentation",
"usvg",
@@ -12079,6 +12080,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773"
dependencies = [
"profiling-procmacros",
+ "tracy-client",
]
[[package]]
@@ -12185,6 +12187,7 @@ dependencies = [
"language",
"menu",
"pretty_assertions",
+ "profiling",
"project",
"rayon",
"schemars 1.0.1",
@@ -12195,6 +12198,7 @@ dependencies = [
"smallvec",
"telemetry",
"theme",
+ "tracy-client",
"ui",
"util",
"workspace",
@@ -13960,6 +13964,7 @@ dependencies = [
"futures 0.3.31",
"parking_lot",
"rand 0.9.1",
+ "tracy-client-sys",
"workspace-hack",
]
@@ -774,6 +774,7 @@ features = [
[patch.crates-io]
notify = { git = "https://github.com/zed-industries/notify.git", rev = "bbb9ea5ae52b253e095737847e367c30653a2e96" }
notify-types = { git = "https://github.com/zed-industries/notify.git", rev = "bbb9ea5ae52b253e095737847e367c30653a2e96" }
+tracy-client = { path = "../rust_tracy_client/tracy-client" }
windows-capture = { git = "https://github.com/zed-industries/windows-capture.git", rev = "f0d6c1b6691db75461b732f6d5ff56eed002eeb9" }
# Makes the workspace hack crate refer to the local one, but only when you're building locally
@@ -41,8 +41,8 @@ uuid.workspace = true
futures.workspace = true
workspace-hack.workspace = true
profiling.workspace = true
-tracy-client-sys.workspace = true
tracy-client.workspace = true
+tracy-client-sys.workspace = true
[dev-dependencies]
pretty_assertions.workspace = true
@@ -58,6 +58,7 @@ async fn get_messages_impl(working_directory: &Path, shas: &[Oid]) -> Result<Vec
}
/// Parse the output of `git diff --name-status -z`
+#[profiling::function]
pub fn parse_git_diff_name_status(content: &str) -> impl Iterator<Item = (&str, StatusCode)> {
let mut parts = content.split('\0');
std::iter::from_fn(move || {
@@ -701,130 +701,118 @@ impl GitRepository for RealGitRepository {
};
dbg!("Load commit");
let git_binary_path = self.any_git_binary_path.clone();
- let _zone = tracy_client::span!("load_commit");
- cx.background_spawn(
- tracy_client::Client::running()
- .expect("tracy client not running")
- .with_fiber("load_commit", async move {
- println!("Starting...");
-
- let show_output = util::command::new_smol_command(&git_binary_path)
- .current_dir(&working_directory)
- .args([
- "--no-optional-locks",
- "show",
- "--format=%P",
- "-z",
- "--no-renames",
- "--name-status",
- ])
- .arg(&commit)
- .stdin(Stdio::null())
- .stdout(Stdio::piped())
- .stderr(Stdio::piped())
- .output()
- .await
- .context("starting git show process")?;
+ cx.background_spawn(async move {
+ let _zone = tracy_client::span_unchecked!();
+ let show_output = util::command::new_smol_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args([
+ "--no-optional-locks",
+ "show",
+ "--format=%P",
+ "-z",
+ "--no-renames",
+ "--name-status",
+ ])
+ .arg(&commit)
+ .stdin(Stdio::null())
+ .stdout(Stdio::piped())
+ .stderr(Stdio::piped())
+ .output()
+ .await
+ .context("starting git show process")?;
- let show_stdout = String::from_utf8_lossy(&show_output.stdout);
- let mut lines = show_stdout.split('\n');
- let parent_sha = lines.next().unwrap().trim().trim_end_matches('\0');
- let changes = parse_git_diff_name_status(lines.next().unwrap_or(""));
+ let show_stdout = String::from_utf8_lossy(&show_output.stdout);
+ let mut lines = show_stdout.split('\n');
+ let parent_sha = lines.next().unwrap().trim().trim_end_matches('\0');
+ let changes = parse_git_diff_name_status(lines.next().unwrap_or(""));
- let mut cat_file_process = util::command::new_smol_command(&git_binary_path)
- .current_dir(&working_directory)
- .args(["--no-optional-locks", "cat-file", "--batch=%(objectsize)"])
- .stdin(Stdio::piped())
- .stdout(Stdio::piped())
- .stderr(Stdio::piped())
- .spawn()
- .context("starting git cat-file process")?;
-
- let mut files = Vec::<CommitFile>::new();
- let mut stdin =
- BufWriter::with_capacity(512, cat_file_process.stdin.take().unwrap());
- let mut stdout = BufReader::new(cat_file_process.stdout.take().unwrap());
- let mut info_line = String::new();
- let mut newline = [b'\0'];
- for (path, status_code) in changes {
- // git-show outputs `/`-delimited paths even on Windows.
- let Some(rel_path) = RelPath::unix(path).log_err() else {
- continue;
- };
-
- match status_code {
- StatusCode::Modified => {
- stdin.write_all(commit.as_bytes()).await?;
- stdin.write_all(b":").await?;
- stdin.write_all(path.as_bytes()).await?;
- stdin.write_all(b"\n").await?;
- stdin.write_all(parent_sha.as_bytes()).await?;
- stdin.write_all(b":").await?;
- stdin.write_all(path.as_bytes()).await?;
- stdin.write_all(b"\n").await?;
- }
- StatusCode::Added => {
- stdin.write_all(commit.as_bytes()).await?;
- stdin.write_all(b":").await?;
- stdin.write_all(path.as_bytes()).await?;
- stdin.write_all(b"\n").await?;
- }
- StatusCode::Deleted => {
- stdin.write_all(parent_sha.as_bytes()).await?;
- stdin.write_all(b":").await?;
- stdin.write_all(path.as_bytes()).await?;
- stdin.write_all(b"\n").await?;
- }
- _ => continue,
- }
- stdin.flush().await?;
+ let mut cat_file_process = util::command::new_smol_command(&git_binary_path)
+ .current_dir(&working_directory)
+ .args(["--no-optional-locks", "cat-file", "--batch=%(objectsize)"])
+ .stdin(Stdio::piped())
+ .stdout(Stdio::piped())
+ .stderr(Stdio::piped())
+ .spawn()
+ .context("starting git cat-file process")?;
+
+ let mut files = Vec::<CommitFile>::new();
+ let mut stdin = BufWriter::with_capacity(512, cat_file_process.stdin.take().unwrap());
+ let mut stdout = BufReader::new(cat_file_process.stdout.take().unwrap());
+ let mut info_line = String::new();
+ let mut newline = [b'\0'];
+ for (path, status_code) in changes {
+ // git-show outputs `/`-delimited paths even on Windows.
+ let Some(rel_path) = RelPath::unix(path).log_err() else {
+ continue;
+ };
+
+ match status_code {
+ StatusCode::Modified => {
+ stdin.write_all(commit.as_bytes()).await?;
+ stdin.write_all(b":").await?;
+ stdin.write_all(path.as_bytes()).await?;
+ stdin.write_all(b"\n").await?;
+ stdin.write_all(parent_sha.as_bytes()).await?;
+ stdin.write_all(b":").await?;
+ stdin.write_all(path.as_bytes()).await?;
+ stdin.write_all(b"\n").await?;
+ }
+ StatusCode::Added => {
+ stdin.write_all(commit.as_bytes()).await?;
+ stdin.write_all(b":").await?;
+ stdin.write_all(path.as_bytes()).await?;
+ stdin.write_all(b"\n").await?;
+ }
+ StatusCode::Deleted => {
+ stdin.write_all(parent_sha.as_bytes()).await?;
+ stdin.write_all(b":").await?;
+ stdin.write_all(path.as_bytes()).await?;
+ stdin.write_all(b"\n").await?;
+ }
+ _ => continue,
+ }
+ stdin.flush().await?;
+ info_line.clear();
+ stdout.read_line(&mut info_line).await?;
+
+ let len = info_line.trim_end().parse().with_context(|| {
+ format!("invalid object size output from cat-file {info_line}")
+ })?;
+ let mut text = vec![0; len];
+ stdout.read_exact(&mut text).await?;
+ stdout.read_exact(&mut newline).await?;
+ let text = String::from_utf8_lossy(&text).to_string();
+
+ let mut old_text = None;
+ let mut new_text = None;
+ match status_code {
+ StatusCode::Modified => {
info_line.clear();
stdout.read_line(&mut info_line).await?;
-
let len = info_line.trim_end().parse().with_context(|| {
- format!("invalid object size output from cat-file {info_line}")
+ format!("invalid object size output from cat-file {}", info_line)
})?;
- let mut text = vec![0; len];
- stdout.read_exact(&mut text).await?;
+ let mut parent_text = vec![0; len];
+ stdout.read_exact(&mut parent_text).await?;
stdout.read_exact(&mut newline).await?;
- let text = String::from_utf8_lossy(&text).to_string();
-
- let mut old_text = None;
- let mut new_text = None;
- match status_code {
- StatusCode::Modified => {
- info_line.clear();
- stdout.read_line(&mut info_line).await?;
- let len = info_line.trim_end().parse().with_context(|| {
- format!(
- "invalid object size output from cat-file {}",
- info_line
- )
- })?;
- let mut parent_text = vec![0; len];
- stdout.read_exact(&mut parent_text).await?;
- stdout.read_exact(&mut newline).await?;
- old_text = Some(String::from_utf8_lossy(&parent_text).to_string());
- new_text = Some(text);
- }
- StatusCode::Added => new_text = Some(text),
- StatusCode::Deleted => old_text = Some(text),
- _ => continue,
- }
-
- files.push(CommitFile {
- path: rel_path.into(),
- old_text,
- new_text,
- })
+ old_text = Some(String::from_utf8_lossy(&parent_text).to_string());
+ new_text = Some(text);
}
+ StatusCode::Added => new_text = Some(text),
+ StatusCode::Deleted => old_text = Some(text),
+ _ => continue,
+ }
- println!("Stopping...");
+ files.push(CommitFile {
+ path: rel_path.into(),
+ old_text,
+ new_text,
+ })
+ }
- Ok(CommitDiff { files })
- }),
- )
+ Ok(CommitDiff { files })
+ })
.boxed()
}
@@ -125,6 +125,7 @@ strum.workspace = true
sum_tree.workspace = true
taffy = "=0.9.0"
thiserror.workspace = true
+tracy-client.workspace = true
util.workspace = true
uuid.workspace = true
waker-fn = "1.2.0"
@@ -168,8 +168,9 @@ impl BackgroundExecutor {
label: Option<TaskLabel>,
) -> Task<R> {
let dispatcher = self.dispatcher.clone();
- let (runnable, task) =
- async_task::spawn(future, move |runnable| dispatcher.dispatch(runnable, label));
+ let (runnable, task) = async_task::spawn(tracy_client::fiber!(future), move |runnable| {
+ dispatcher.dispatch(runnable, label)
+ });
runnable.schedule();
Task(TaskState::Spawned(task))
}
@@ -36,6 +36,7 @@ serde_json.workspace = true
settings.workspace = true
smallvec.workspace = true
theme.workspace = true
+profiling.workspace = true
rayon.workspace = true
ui.workspace = true
util.workspace = true
@@ -45,6 +46,7 @@ workspace.workspace = true
language.workspace = true
zed_actions.workspace = true
telemetry.workspace = true
+tracy-client.workspace = true
workspace-hack.workspace = true
[dev-dependencies]
@@ -3175,6 +3175,7 @@ impl ProjectPanel {
}
}
+ #[profiling::function]
fn update_visible_entries(
&mut self,
new_selected_entry: Option<(WorktreeId, ProjectEntryId)>,
@@ -3207,6 +3208,7 @@ impl ProjectPanel {
self.update_visible_entries_task = cx.spawn_in(window, async move |this, cx| {
let new_state = cx
.background_spawn(async move {
+ let _zone = tracy_client::span_unchecked!();
for worktree_snapshot in visible_worktrees {
let worktree_id = worktree_snapshot.id();
@@ -4227,6 +4229,7 @@ impl ProjectPanel {
false
}
+ #[profiling::function]
fn render_entry(
&self,
entry_id: ProjectEntryId,
@@ -5152,6 +5155,7 @@ impl ProjectPanel {
None
}
+ #[profiling::function]
fn render_sticky_entries(
&self,
child: StickyProjectPanelCandidate,
@@ -5288,6 +5292,7 @@ fn item_width_estimate(depth: usize, item_text_chars: usize, is_symlink: bool) -
}
impl Render for ProjectPanel {
+ #[profiling::function]
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let has_worktree = !self.state.visible_entries.is_empty();
let project = self.project.read(cx);
@@ -6041,6 +6046,7 @@ pub fn sort_worktree_entries(entries: &mut [impl AsRef<Entry>]) {
entries.sort_by(|lhs, rhs| cmp(lhs, rhs));
}
+#[profiling::function]
pub fn par_sort_worktree_entries(entries: &mut Vec<GitEntry>) {
entries.par_sort_by(|lhs, rhs| cmp(lhs, rhs));
}
@@ -22,4 +22,5 @@ chrono.workspace = true
futures.workspace = true
parking_lot.workspace = true
rand.workspace = true
+tracy-client-sys.workspace = true
workspace-hack.workspace = true
@@ -19,7 +19,7 @@ name = "zed"
path = "src/main.rs"
[features]
-profile-with-tracy = ["dep:tracy-client"]#, "profiling/profile-with-tracy"]
+profile-with-tracy = ["dep:tracy-client", "profiling/profile-with-tracy"]
profile-with-tracy-memory = ["profile-with-tracy"]
[dependencies]