summaryrefslogtreecommitdiff
path: root/t/perf
diff options
context:
space:
mode:
Diffstat (limited to 't/perf')
-rw-r--r--t/perf/.gitignore1
-rw-r--r--t/perf/Makefile4
-rwxr-xr-xt/perf/p2000-sparse-operations.sh101
-rwxr-xr-xt/perf/p4205-log-pretty-formats.sh2
-rwxr-xr-xt/perf/p5303-many-packs.sh36
-rwxr-xr-xt/perf/p5310-pack-bitmaps.sh14
-rwxr-xr-xt/perf/p5600-partial-clone.sh16
-rwxr-xr-xt/perf/p7519-fsmonitor.sh75
-rw-r--r--t/perf/perf-lib.sh36
9 files changed, 256 insertions, 29 deletions
diff --git a/t/perf/.gitignore b/t/perf/.gitignore
index 982eb8e3a9..72f5d0d314 100644
--- a/t/perf/.gitignore
+++ b/t/perf/.gitignore
@@ -1,3 +1,4 @@
/build/
/test-results/
+/test-trace/
/trash directory*/
diff --git a/t/perf/Makefile b/t/perf/Makefile
index fcb0e8865e..2465770a78 100644
--- a/t/perf/Makefile
+++ b/t/perf/Makefile
@@ -7,10 +7,10 @@ perf: pre-clean
./run
pre-clean:
- rm -rf test-results
+ rm -rf test-results test-trace
clean:
- rm -rf build "trash directory".* test-results
+ rm -rf build "trash directory".* test-results test-trace
test-lint:
$(MAKE) -C .. test-lint
diff --git a/t/perf/p2000-sparse-operations.sh b/t/perf/p2000-sparse-operations.sh
new file mode 100755
index 0000000000..94513c9774
--- /dev/null
+++ b/t/perf/p2000-sparse-operations.sh
@@ -0,0 +1,101 @@
+#!/bin/sh
+
+test_description="test performance of Git operations using the index"
+
+. ./perf-lib.sh
+
+test_perf_default_repo
+
+SPARSE_CONE=f2/f4/f1
+
+test_expect_success 'setup repo and indexes' '
+ git reset --hard HEAD &&
+
+ # Remove submodules from the example repo, because our
+ # duplication of the entire repo creates an unlikely data shape.
+ if git config --file .gitmodules --get-regexp "submodule.*.path" >modules
+ then
+ git rm $(awk "{print \$2}" modules) &&
+ git commit -m "remove submodules" || return 1
+ fi &&
+
+ echo bogus >a &&
+ cp a b &&
+ git add a b &&
+ git commit -m "level 0" &&
+ BLOB=$(git rev-parse HEAD:a) &&
+ OLD_COMMIT=$(git rev-parse HEAD) &&
+ OLD_TREE=$(git rev-parse HEAD^{tree}) &&
+
+ for i in $(test_seq 1 4)
+ do
+ cat >in <<-EOF &&
+ 100755 blob $BLOB a
+ 040000 tree $OLD_TREE f1
+ 040000 tree $OLD_TREE f2
+ 040000 tree $OLD_TREE f3
+ 040000 tree $OLD_TREE f4
+ EOF
+ NEW_TREE=$(git mktree <in) &&
+ NEW_COMMIT=$(git commit-tree $NEW_TREE -p $OLD_COMMIT -m "level $i") &&
+ OLD_TREE=$NEW_TREE &&
+ OLD_COMMIT=$NEW_COMMIT || return 1
+ done &&
+
+ git sparse-checkout init --cone &&
+ git branch -f wide $OLD_COMMIT &&
+ git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . full-index-v3 &&
+ (
+ cd full-index-v3 &&
+ git sparse-checkout init --cone &&
+ git sparse-checkout set $SPARSE_CONE &&
+ git config index.version 3 &&
+ git update-index --index-version=3
+ ) &&
+ git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . full-index-v4 &&
+ (
+ cd full-index-v4 &&
+ git sparse-checkout init --cone &&
+ git sparse-checkout set $SPARSE_CONE &&
+ git config index.version 4 &&
+ git update-index --index-version=4
+ ) &&
+ git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . sparse-index-v3 &&
+ (
+ cd sparse-index-v3 &&
+ git sparse-checkout init --cone --sparse-index &&
+ git sparse-checkout set $SPARSE_CONE &&
+ git config index.version 3 &&
+ git update-index --index-version=3
+ ) &&
+ git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . sparse-index-v4 &&
+ (
+ cd sparse-index-v4 &&
+ git sparse-checkout init --cone --sparse-index &&
+ git sparse-checkout set $SPARSE_CONE &&
+ git config index.version 4 &&
+ git update-index --index-version=4
+ )
+'
+
+test_perf_on_all () {
+ command="$@"
+ for repo in full-index-v3 full-index-v4 \
+ sparse-index-v3 sparse-index-v4
+ do
+ test_perf "$command ($repo)" "
+ (
+ cd $repo &&
+ echo >>$SPARSE_CONE/a &&
+ $command
+ )
+ "
+ done
+}
+
+test_perf_on_all git status
+test_perf_on_all git add -A
+test_perf_on_all git add .
+test_perf_on_all git commit -a -m A
+
+test_done
diff --git a/t/perf/p4205-log-pretty-formats.sh b/t/perf/p4205-log-pretty-formats.sh
index 7c26f4f337..609fecd65d 100755
--- a/t/perf/p4205-log-pretty-formats.sh
+++ b/t/perf/p4205-log-pretty-formats.sh
@@ -6,7 +6,7 @@ test_description='Tests the performance of various pretty format placeholders'
test_perf_default_repo
-for format in %H %h %T %t %P %p %h-%h-%h
+for format in %H %h %T %t %P %p %h-%h-%h %an-%ae-%s
do
test_perf "log with $format" "
git log --format=\"$format\" >/dev/null
diff --git a/t/perf/p5303-many-packs.sh b/t/perf/p5303-many-packs.sh
index ce0c42cc9f..35c0cbdf49 100755
--- a/t/perf/p5303-many-packs.sh
+++ b/t/perf/p5303-many-packs.sh
@@ -28,11 +28,18 @@ repack_into_n () {
push @commits, $_ if $. % 5 == 1;
}
print reverse @commits;
- ' "$1" >pushes
+ ' "$1" >pushes &&
# create base packfile
- head -n 1 pushes |
- git pack-objects --delta-base-offset --revs staging/pack
+ base_pack=$(
+ head -n 1 pushes |
+ git pack-objects --delta-base-offset --revs staging/pack
+ ) &&
+ test_export base_pack &&
+
+ # create an empty packfile
+ empty_pack=$(git pack-objects staging/pack </dev/null) &&
+ test_export empty_pack &&
# and then incrementals between each pair of commits
last= &&
@@ -49,6 +56,12 @@ repack_into_n () {
last=$rev
done <pushes &&
+ (
+ find staging -type f -name 'pack-*.pack' |
+ xargs -n 1 basename | grep -v "$base_pack" &&
+ printf "^pack-%s.pack\n" $base_pack
+ ) >stdin.packs
+
# and install the whole thing
rm -f .git/objects/pack/* &&
mv staging/* .git/objects/pack/
@@ -91,6 +104,23 @@ do
--reflog --indexed-objects --delta-base-offset \
--stdout </dev/null >/dev/null
'
+
+ test_perf "repack with kept ($nr_packs)" '
+ git pack-objects --keep-true-parents \
+ --keep-pack=pack-$empty_pack.pack \
+ --honor-pack-keep --non-empty --all \
+ --reflog --indexed-objects --delta-base-offset \
+ --stdout </dev/null >/dev/null
+ '
+
+ test_perf "repack with --stdin-packs ($nr_packs)" '
+ git pack-objects \
+ --keep-true-parents \
+ --stdin-packs \
+ --non-empty \
+ --delta-base-offset \
+ --stdout <stdin.packs >/dev/null
+ '
done
# Measure pack loading with 10,000 packs.
diff --git a/t/perf/p5310-pack-bitmaps.sh b/t/perf/p5310-pack-bitmaps.sh
index b3e725f031..452be01056 100755
--- a/t/perf/p5310-pack-bitmaps.sh
+++ b/t/perf/p5310-pack-bitmaps.sh
@@ -15,6 +15,12 @@ test_expect_success 'setup bitmap config' '
git config pack.writebitmaps true
'
+# we need to create the tag up front such that it is covered by the repack and
+# thus by generated bitmaps.
+test_expect_success 'create tags' '
+ git tag --message="tag pointing to HEAD" perf-tag HEAD
+'
+
test_perf 'repack to disk' '
git repack -ad
'
@@ -43,6 +49,14 @@ test_perf 'rev-list (objects)' '
git rev-list --all --use-bitmap-index --objects >/dev/null
'
+test_perf 'rev-list with tag negated via --not --all (objects)' '
+ git rev-list perf-tag --not --all --use-bitmap-index --objects >/dev/null
+'
+
+test_perf 'rev-list with negative tag (objects)' '
+ git rev-list HEAD --not perf-tag --use-bitmap-index --objects >/dev/null
+'
+
test_perf 'rev-list count with blob:none' '
git rev-list --use-bitmap-index --count --objects --all \
--filter=blob:none >/dev/null
diff --git a/t/perf/p5600-partial-clone.sh b/t/perf/p5600-partial-clone.sh
index 3e04bd2ae1..a965f2c4d6 100755
--- a/t/perf/p5600-partial-clone.sh
+++ b/t/perf/p5600-partial-clone.sh
@@ -23,4 +23,20 @@ test_perf 'checkout of result' '
git -C worktree checkout -f
'
+test_perf 'fsck' '
+ git -C bare.git fsck
+'
+
+test_perf 'count commits' '
+ git -C bare.git rev-list --all --count
+'
+
+test_perf 'count non-promisor commits' '
+ git -C bare.git rev-list --all --count --exclude-promisor-objects
+'
+
+test_perf 'gc' '
+ git -C bare.git gc
+'
+
test_done
diff --git a/t/perf/p7519-fsmonitor.sh b/t/perf/p7519-fsmonitor.sh
index 1e20a184c7..5eb5044a10 100755
--- a/t/perf/p7519-fsmonitor.sh
+++ b/t/perf/p7519-fsmonitor.sh
@@ -32,6 +32,8 @@ test_description="Test core.fsmonitor"
#
# GIT_PERF_7519_DROP_CACHE: if set, the OS caches are dropped between tests
#
+# GIT_PERF_7519_TRACE: if set, enable trace logging during the test.
+# Trace logs will be grouped by fsmonitor provider.
test_perf_large_repo
test_checkout_worktree
@@ -70,6 +72,32 @@ then
fi
fi
+trace_start() {
+ if test -n "$GIT_PERF_7519_TRACE"
+ then
+ name="$1"
+ TEST_TRACE_DIR="$TEST_OUTPUT_DIRECTORY/test-trace/p7519/"
+ echo "Writing trace logging to $TEST_TRACE_DIR"
+
+ mkdir -p "$TEST_TRACE_DIR"
+
+ # Start Trace2 logging and any other GIT_TRACE_* logs that you
+ # want for this named test case.
+
+ GIT_TRACE2_PERF="$TEST_TRACE_DIR/$name.trace2perf"
+ export GIT_TRACE2_PERF
+
+ >"$GIT_TRACE2_PERF"
+ fi
+}
+
+trace_stop() {
+ if test -n "$GIT_PERF_7519_TRACE"
+ then
+ unset GIT_TRACE2_PERF
+ fi
+}
+
test_expect_success "one time repo setup" '
# set untrackedCache depending on the environment
if test -n "$GIT_PERF_7519_UNTRACKED_CACHE"
@@ -101,7 +129,7 @@ test_expect_success "one time repo setup" '
# If Watchman exists, watch the work tree and attempt a query.
if test_have_prereq WATCHMAN; then
watchman watch "$GIT_WORK_TREE" &&
- watchman watch-list | grep -q -F "$GIT_WORK_TREE"
+ watchman watch-list | grep -q -F "p7519-fsmonitor"
fi
'
@@ -169,8 +197,18 @@ test_fsmonitor_suite() {
git status -uall
'
+ # Update the mtimes on upto 100k files to make status think
+ # that they are dirty. For simplicity, omit any files with
+ # LFs (i.e. anything that ls-files thinks it needs to dquote).
+ # Then fully backslash-quote the paths to capture any
+ # whitespace so that they pass thru xargs properly.
+ #
test_perf_w_drop_caches "status (dirty) ($DESC)" '
- git ls-files | head -100000 | xargs -d "\n" touch -h &&
+ git ls-files | \
+ head -100000 | \
+ grep -v \" | \
+ sed '\''s/\(.\)/\\\1/g'\'' | \
+ xargs test-tool chmtime -300 &&
git status
'
@@ -178,6 +216,10 @@ test_fsmonitor_suite() {
git diff
'
+ test_perf_w_drop_caches "diff HEAD ($DESC)" '
+ git diff HEAD
+ '
+
test_perf_w_drop_caches "diff -- 0_files ($DESC)" '
git diff -- 1_file
'
@@ -203,6 +245,12 @@ test_fsmonitor_suite() {
'
}
+#
+# Run a full set of perf tests using each Hook-based fsmonitor provider,
+# such as Watchman.
+#
+
+trace_start fsmonitor-watchman
if test -n "$GIT_PERF_7519_FSMONITOR"; then
for INTEGRATION_PATH in $GIT_PERF_7519_FSMONITOR; do
test_expect_success "setup for fsmonitor $INTEGRATION_PATH" 'setup_for_fsmonitor'
@@ -213,14 +261,6 @@ else
test_fsmonitor_suite
fi
-test_expect_success "setup without fsmonitor" '
- unset INTEGRATION_SCRIPT &&
- git config --unset core.fsmonitor &&
- git update-index --no-fsmonitor
-'
-
-test_fsmonitor_suite
-
if test_have_prereq WATCHMAN
then
watchman watch-del "$GIT_WORK_TREE" >/dev/null 2>&1 &&
@@ -229,5 +269,20 @@ then
# preventing the removal of the trash directory
watchman shutdown-server >/dev/null 2>&1
fi
+trace_stop
+
+#
+# Run a full set of perf tests with the fsmonitor feature disabled.
+#
+
+trace_start fsmonitor-disabled
+test_expect_success "setup without fsmonitor" '
+ unset INTEGRATION_SCRIPT &&
+ git config --unset core.fsmonitor &&
+ git update-index --no-fsmonitor
+'
+
+test_fsmonitor_suite
+trace_stop
test_done
diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh
index 22d727cef8..601d9f67dd 100644
--- a/t/perf/perf-lib.sh
+++ b/t/perf/perf-lib.sh
@@ -70,6 +70,19 @@ test_perf_do_repo_symlink_config_ () {
test_have_prereq SYMLINKS || git config core.symlinks false
}
+test_perf_copy_repo_contents () {
+ for stuff in "$1"/*
+ do
+ case "$stuff" in
+ */objects|*/hooks|*/config|*/commondir|*/gitdir|*/worktrees)
+ ;;
+ *)
+ cp -R "$stuff" "$repo/.git/" || exit 1
+ ;;
+ esac
+ done
+}
+
test_perf_create_repo_from () {
test "$#" = 2 ||
BUG "not 2 parameters to test-create-repo"
@@ -77,20 +90,20 @@ test_perf_create_repo_from () {
source="$2"
source_git="$("$MODERN_GIT" -C "$source" rev-parse --git-dir)"
objects_dir="$("$MODERN_GIT" -C "$source" rev-parse --git-path objects)"
+ common_dir="$("$MODERN_GIT" -C "$source" rev-parse --git-common-dir)"
mkdir -p "$repo/.git"
(
cd "$source" &&
{ cp -Rl "$objects_dir" "$repo/.git/" 2>/dev/null ||
cp -R "$objects_dir" "$repo/.git/"; } &&
- for stuff in "$source_git"/*; do
- case "$stuff" in
- */objects|*/hooks|*/config|*/commondir)
- ;;
- *)
- cp -R "$stuff" "$repo/.git/" || exit 1
- ;;
- esac
- done
+
+ # common_dir must come first here, since we want source_git to
+ # take precedence and overwrite any overlapping files
+ test_perf_copy_repo_contents "$common_dir"
+ if test "$source_git" != "$common_dir"
+ then
+ test_perf_copy_repo_contents "$source_git"
+ fi
) &&
(
cd "$repo" &&
@@ -147,10 +160,7 @@ test_run_perf_ () {
"$GTIME" -f "%E %U %S" -o test_time.$i "$SHELL" -c '
. '"$TEST_DIRECTORY"/test-lib-functions.sh'
test_export () {
- [ $# != 0 ] || return 0
- test_export_="$test_export_ $1"
- shift
- test_export "$@"
+ test_export_="$test_export_ $*"
}
'"$1"'
ret=$?