gix-blame performance improved by a change in gix-diff
code
analysis
Author
Christoph Rüßler
Published
March 14, 2026
Modified
August 10, 2026
Note
This post is a modernized version of an earlier post of mine in my main blog.
This post’s “published” date reflects the date the original post was published.
In February 2026, we got a PR in gitoxide that substantially improved gix-diff’s tree diff performance. Since gix-blame’s algorithm uses a lot of tree diffs under the hood, I wanted to know what the impact on gix-blame’s performance was.
I set up a benchmark using hyperfine, and the results are quite impressive: speedups of more than 20 % in some scenarios, with no noticeable performance degradation in any of the scenarios I included. From what I can tell, the speedup depends on the directory depth at which the blamed file lives. This is plausible because nested tree diffs are more expensive than flat ones.
Running the benchmark
The comparison was run between this commit that contained the optimization and its parent. After compiling both executables with cargo build --release --locked, I ran the following script to collect some data using hyperfine.
This will create a couple of Markdown files, benchmark-1.json through benchmark-9.json.
Loading the data
Then, in order to work with these files, we’re going to use numpy and pandas to load them into data.
A few helper functions for loading the data
import numpy as npimport pandas as pdimport matplotlib as mplimport seaborn as snsimport jsondef load_results(filename):withopen(filename) as f:return json.load(f)["results"]def extract_data_points(result): command = result["command"] path = result["parameters"]["path"]return {"command": command, "path": path, "time": result["times"]}
filenames = [f"benchmark-{i}.json"for i inrange(1, 10)]results = [load_results(filename) for filename in filenames]results = [extract_data_points(result) for result in np.concatenate(results)]data = pd.concat( [pd.DataFrame(result) for result in results], ignore_index=True,)
And finally, we’re going to create 2 plots that will give us an idea of how both versions of gix blame compare with respect to performance. In both plots, there’s a clearly visible speedup associated with the change. It’s also clearly visible that the speedup is much more pronounced for files nested a few directories deep.
The aggregated data confirm the visual impression: for files in the repository’s root directory, there’s only a small performance improvement, but for deeper hierarchies, there’s large improvements of more than 20 % in some cases.