From 4c5740779a88059e2fa547bfac2b275cc886e869 Mon Sep 17 00:00:00 2001 From: Waleed Khan Date: Sun, 5 Sep 2021 00:09:02 -0500 Subject: [PATCH] bench: add `cherrypick_fast` benchmark The results on the gecko-dev repository (https://github.com/mozilla/gecko-dev) show around 500x speedup for in-memory cherry-picks: ``` $ PATH_TO_REPO="$HOME/workspace/gecko-dev" cargo bench cherrypick Benchmarking Cherrypick/Repo::cherrypick_commit: Warming up for 3.0000 s Warning: Unable to complete 10 samples in 5.0s. You may wish to increase target time to 19.0s. Cherrypick/Repo::cherrypick_commit time: [1.8935 s 1.9011 s 1.9088 s] change: [-1.7816% +2.5204% +7.0223%] (p = 0.29 > 0.05) No change in performance detected. Cherrypick/Repo::cherrypick_fast time: [2.7665 ms 2.8209 ms 2.9297 ms] change: [-1.1128% +1.4992% +4.9619%] (p = 0.38 > 0.05) No change in performance detected. ``` --- CHANGELOG.md | 1 + benches/benches.rs | 41 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abd79b94c..892fb529a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed: Flickering in `git undo`'s rendering has been reduced. - Fixed: Commits made via `git merge` are now recorded in the event log. - Fixed: Long progress messages are now truncated on narrow screens. +- Fixed: In-memory rebases on large repositories are now up to 500x faster. ## [0.3.4] - 2021-08-12 diff --git a/benches/benches.rs b/benches/benches.rs index 4deffe240..f79eec65f 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -5,7 +5,7 @@ use branchless::core::formatting::Glyphs; use branchless::core::graph::{make_graph, BranchOids, HeadOid, MainBranchOid}; use branchless::core::mergebase::{make_merge_base_db, MergeBaseDb}; use branchless::core::rewrite::{BuildRebasePlanOptions, RebasePlanBuilder}; -use branchless::git::{Commit, Repo}; +use branchless::git::{CherryPickFastOptions, Commit, Repo}; use branchless::tui::Effects; use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; @@ -111,9 +111,46 @@ fn bench_find_path_to_merge_base(c: &mut Criterion) { }); } +fn bench_cherrypick_fast(c: &mut Criterion) { + let mut group = c.benchmark_group("Cherrypick"); + group.sample_size(10); + group.bench_function("Repo::cherrypick_commit", |b| { + let repo = get_repo(); + let head_oid = repo.get_head_info().unwrap().oid.unwrap(); + let head_commit = repo.find_commit_or_fail(head_oid).unwrap(); + let target_commit = nth_parent(head_commit.clone(), 1); + + b.iter(|| { + let mut index = repo + .cherrypick_commit(&head_commit, &target_commit, 0) + .unwrap(); + let tree_oid = repo.write_index_to_tree(&mut index).unwrap(); + repo.find_tree(tree_oid).unwrap().unwrap() + }) + }); + group.bench_function("Repo::cherrypick_fast", |b| { + let repo = get_repo(); + let head_oid = repo.get_head_info().unwrap().oid.unwrap(); + let head_commit = repo.find_commit_or_fail(head_oid).unwrap(); + let target_commit = nth_parent(head_commit.clone(), 1); + + b.iter(|| { + repo.cherrypick_fast( + &head_commit, + &target_commit, + &CherryPickFastOptions { + reuse_parent_tree_if_possible: false, + }, + ) + .unwrap() + .unwrap(); + }); + }); +} + criterion_group!( name = benches; config = Criterion::default().sample_size(10); - targets = bench_rebase_plan, bench_find_path_to_merge_base + targets = bench_rebase_plan, bench_find_path_to_merge_base, bench_cherrypick_fast ); criterion_main!(benches);