# Speed up StreamingDiff::push_new by 30-36% \(\#57772\) · gitcafe/zed

[View on GitCafe](https://git.cafe/gitcafe/zed/commit/6afac23e4a9f2ce87f4baff678dd523d45b05aa1)

Repository: [gitcafe/zed](https://git.cafe/gitcafe/zed)

Visibility: public

Requested revision: 6afac23e4a9f2ce87f4baff678dd523d45b05aa1

Requested commit: 6afac23e4a9f2ce87f4baff678dd523d45b05aa1

Commit: 6afac23e4a9f2ce87f4baff678dd523d45b05aa1

Tree: 1c67c9566cfaee49869ed2b9449f280c532018ca

Author: Anthony Eid

Committer: GitHub

## Message

````
Speed up StreamingDiff::push_new by 30-36% (#57772)

## Motivation

Miniprofs of Zed dropping frames showed foreground thread stalls of
711.56 ms, 641.01 ms, and 221.99 ms from the `edit_file_tool`. The new
benchmark isolated `StreamingDiff::push_new` as one of the expensive
phases so this PR aims to speed it up so we can avoid dropping more
frames in the future.

## Benchmark methodology

I had an agent create a Criterion suite with four deterministic Rust
edit fixtures: tiny localized rewrite, small localized rewrite, many
small changes, and helper block insertions.

Benchmarked with:

```sh
cargo bench -p streaming_diff --bench streaming_diff --profile release-fast -- --warm-up-time 1 --measurement-time 2
```

The benchmark binary was also recorded under `xctrace` CPU Counters to
inspect CPU samples before and after the change.

## Results

`StreamingDiff::push_new` improved across all fixtures:

| Benchmark | Before | After | Improvement |
|---|---:|---:|---:|
| `tiny_function_rewrite` | ~10.81 ms | ~6.91 ms | ~36% faster |
| `small_function_rewrite` | ~51.02 ms | ~35.39 ms | ~31% faster |
| `medium_many_small_changes` | ~130.71 ms | ~83.83 ms | ~36% faster |
| `medium_insertions` | ~120.52 ms | ~79.90 ms | ~34% faster |

The `xctrace` baseline showed samples in `Hash::hash`,
`RandomState::hash_one`, `HashMap::insert`, and
`RawTable::reserve_rehash`. After replacing the map with two `Vec<u32>`
row buffers, the hash table frames disappeared from the top samples.

The speedup comes from removing hash work from the DP inner loop and
replacing scattered hash table probes with contiguous row buffer access
(better cache hits 🏎️). The trace did not include direct cache miss
counts, but this layout is likely more cache friendly because it
replaces hash table access with a continuous line of memory (the
`Vec`s).

Release Notes:

- N/A
````

## Parents

- [9b4737b0d78b17ee33f8d916a946bc6c34cd9742](https://git.cafe/gitcafe/zed/commit/9b4737b0d78b17ee33f8d916a946bc6c34cd9742?format=markdown)

[Source at this commit](https://git.cafe/gitcafe/zed/tree/6afac23e4a9f2ce87f4baff678dd523d45b05aa1?format=markdown)
