Skip to content

Commit

Permalink
project search: Render results in batches (#16960)
Browse files Browse the repository at this point in the history
This improves performance, because we don't render after every single
match/range that was added to the results.

I think for my example search it's twice as fast?

## Numbers

Recorded in debug mode (because it's 6:30pm and my poor computer has
spun its fan enough for today and also because you can see the change of
the effect more in debug mode), rendering `<` searched in `zed.dev`
repo:

- Before: `14.59558225s`
- After: `2.604320875s`




## Videos
Before (recorded in release mode):



https://github.com/user-attachments/assets/909260fa-3e69-49ab-8786-dd384e2a27ee

After (recorded in release mode):



https://github.com/user-attachments/assets/fc8a85d3-e575-470f-b59c-16a6df8b3f80
## Release Notes

Release Notes:

- Improved performance of rendering project-search results in the
multi-buffer after finding them.
  • Loading branch information
mrnugget authored Aug 27, 2024
1 parent ff26abd commit 1d868e1
Showing 1 changed file with 47 additions and 27 deletions.
74 changes: 47 additions & 27 deletions crates/search/src/project_search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,36 +221,56 @@ impl ProjectSearch {

let mut limit_reached = false;
while let Some(results) = matches.next().await {
for result in results {
match result {
project::search::SearchResult::Buffer { buffer, ranges } => {
let mut match_ranges = this
.update(&mut cx, |this, cx| {
this.excerpts.update(cx, |excerpts, cx| {
excerpts.stream_excerpts_with_context_lines(
buffer,
ranges,
editor::DEFAULT_MULTIBUFFER_CONTEXT,
cx,
)
})
})
.ok()?;

while let Some(range) = match_ranges.next().await {
this.update(&mut cx, |this, _| {
this.no_results = Some(false);
this.match_ranges.push(range)
})
.ok()?;
let tasks = results
.into_iter()
.map(|result| {
let this = this.clone();

cx.spawn(|mut cx| async move {
match result {
project::search::SearchResult::Buffer { buffer, ranges } => {
let mut match_ranges_rx =
this.update(&mut cx, |this, cx| {
this.excerpts.update(cx, |excerpts, cx| {
excerpts.stream_excerpts_with_context_lines(
buffer,
ranges,
editor::DEFAULT_MULTIBUFFER_CONTEXT,
cx,
)
})
})?;

let mut match_ranges = vec![];
while let Some(range) = match_ranges_rx.next().await {
match_ranges.push(range);
}
anyhow::Ok((match_ranges, false))
}
project::search::SearchResult::LimitReached => {
anyhow::Ok((vec![], true))
}
}
this.update(&mut cx, |_, cx| cx.notify()).ok()?;
}
project::search::SearchResult::LimitReached => {
limit_reached = true;
}
})
})
.collect::<Vec<_>>();

let result_ranges = futures::future::join_all(tasks).await;
let mut combined_ranges = vec![];
for (ranges, result_limit_reached) in result_ranges.into_iter().flatten() {
combined_ranges.extend(ranges);
if result_limit_reached {
limit_reached = result_limit_reached;
}
}
this.update(&mut cx, |this, cx| {
if !combined_ranges.is_empty() {
this.no_results = Some(false);
this.match_ranges.extend(combined_ranges);
cx.notify();
}
})
.ok()?;
}

this.update(&mut cx, |this, cx| {
Expand Down

0 comments on commit 1d868e1

Please sign in to comment.