diff options
author | Junio C Hamano <gitster@pobox.com> | 2023-12-10 03:37:50 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2023-12-10 03:37:50 +0300 |
commit | 98d0a1f93e869b29041de9122fe31a62c40a4e78 (patch) | |
tree | 91b04459a87509efef99f4bb4098245ad0dd8a33 /t/perf | |
parent | e020e55a62dc3281504858d4091847d18ca63b2d (diff) | |
parent | 294bfc24418e81dfb204d14a3c3c24af9b195179 (diff) |
Merge branch 'vd/for-each-ref-unsorted-optimization'
"git for-each-ref --no-sort" still sorted the refs alphabetically
which paid non-trivial cost. It has been redefined to show output
in an unspecified order, to allow certain optimizations to take
advantage of.
* vd/for-each-ref-unsorted-optimization:
t/perf: add perf tests for for-each-ref
ref-filter.c: use peeled tag for '*' format fields
for-each-ref: clean up documentation of --format
ref-filter.c: filter & format refs in the same callback
ref-filter.c: refactor to create common helper functions
ref-filter.c: rename 'ref_filter_handler()' to 'filter_one()'
ref-filter.h: add functions for filter/format & format-only
ref-filter.h: move contains caches into filter
ref-filter.h: add max_count and omit_empty to ref_format
ref-filter.c: really don't sort when using --no-sort
Diffstat (limited to 't/perf')
-rwxr-xr-x | t/perf/p6300-for-each-ref.sh | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/t/perf/p6300-for-each-ref.sh b/t/perf/p6300-for-each-ref.sh new file mode 100755 index 0000000000..fa7289c752 --- /dev/null +++ b/t/perf/p6300-for-each-ref.sh @@ -0,0 +1,87 @@ +#!/bin/sh + +test_description='performance of for-each-ref' +. ./perf-lib.sh + +test_perf_fresh_repo + +ref_count_per_type=10000 +test_iteration_count=10 + +test_expect_success "setup" ' + test_commit_bulk $(( 1 + $ref_count_per_type )) && + + # Create refs + test_seq $ref_count_per_type | + sed "s,.*,update refs/heads/branch_& HEAD~&\nupdate refs/custom/special_& HEAD~&," | + git update-ref --stdin && + + # Create annotated tags + for i in $(test_seq $ref_count_per_type) + do + # Base tags + echo "tag tag_$i" && + echo "mark :$i" && + echo "from HEAD~$i" && + printf "tagger %s <%s> %s\n" \ + "$GIT_COMMITTER_NAME" \ + "$GIT_COMMITTER_EMAIL" \ + "$GIT_COMMITTER_DATE" && + echo "data <<EOF" && + echo "tag $i" && + echo "EOF" && + + # Nested tags + echo "tag nested_$i" && + echo "from :$i" && + printf "tagger %s <%s> %s\n" \ + "$GIT_COMMITTER_NAME" \ + "$GIT_COMMITTER_EMAIL" \ + "$GIT_COMMITTER_DATE" && + echo "data <<EOF" && + echo "nested tag $i" && + echo "EOF" || return 1 + done | git fast-import +' + +test_for_each_ref () { + title="for-each-ref" + if test $# -gt 0; then + title="$title ($1)" + shift + fi + args="$@" + + test_perf "$title" " + for i in \$(test_seq $test_iteration_count); do + git for-each-ref $args >/dev/null + done + " +} + +run_tests () { + test_for_each_ref "$1" + test_for_each_ref "$1, no sort" --no-sort + test_for_each_ref "$1, --count=1" --count=1 + test_for_each_ref "$1, --count=1, no sort" --no-sort --count=1 + test_for_each_ref "$1, tags" refs/tags/ + test_for_each_ref "$1, tags, no sort" --no-sort refs/tags/ + test_for_each_ref "$1, tags, dereferenced" '--format="%(refname) %(objectname) %(*objectname)"' refs/tags/ + test_for_each_ref "$1, tags, dereferenced, no sort" --no-sort '--format="%(refname) %(objectname) %(*objectname)"' refs/tags/ + + test_perf "for-each-ref ($1, tags) + cat-file --batch-check (dereferenced)" " + for i in \$(test_seq $test_iteration_count); do + git for-each-ref --format='%(objectname)^{} %(refname) %(objectname)' refs/tags/ | \ + git cat-file --batch-check='%(objectname) %(rest)' >/dev/null + done + " +} + +run_tests "loose" + +test_expect_success 'pack refs' ' + git pack-refs --all +' +run_tests "packed" + +test_done |