Merge branch 'ab/perf-wildmatch'
authorJunio C Hamano <gitster@pobox.com>
Tue, 30 May 2017 02:16:40 +0000 (11:16 +0900)
committerJunio C Hamano <gitster@pobox.com>
Tue, 30 May 2017 02:16:41 +0000 (11:16 +0900)
Add perf-test for wildmatch.

* ab/perf-wildmatch:
perf: add test showing exponential growth in path globbing
perf: add function to setup a fresh test repo

t/perf/README
t/perf/p0100-globbing.sh [new file with mode: 0755]
t/perf/perf-lib.sh
index 49ea4349bedfc53b5b565cf1102c74ccb93ab653..de2fe1569603eac1316d7c5a7224e2617f0cb996 100644 (file)
@@ -106,6 +106,7 @@ sources perf-lib.sh:
 
 After that you will want to use some of the following:
 
+       test_perf_fresh_repo    # sets up an empty repository
        test_perf_default_repo  # sets up a "normal" repository
        test_perf_large_repo    # sets up a "large" repository
 
diff --git a/t/perf/p0100-globbing.sh b/t/perf/p0100-globbing.sh
new file mode 100755 (executable)
index 0000000..dd18a9c
--- /dev/null
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+test_description="Tests pathological globbing performance
+
+Shows how Git's globbing performance performs when given the sort of
+pathological patterns described in at https://research.swtch.com/glob
+"
+
+. ./perf-lib.sh
+
+test_globs_big='10 25 50 75 100'
+test_globs_small='1 2 3 4 5 6'
+
+test_perf_fresh_repo
+
+test_expect_success 'setup' '
+       for i in $(test_seq 1 100)
+       do
+               printf "a" >>refname &&
+               for j in $(test_seq 1 $i)
+               do
+                       printf "a*" >>refglob.$i
+               done &&
+               echo b >>refglob.$i
+       done &&
+       test_commit test $(cat refname).t "" $(cat refname).t
+'
+
+for i in $test_globs_small
+do
+       test_perf "refglob((a*)^nb) against tag (a^100).t; n = $i" '
+               git for-each-ref "refs/tags/$(cat refglob.'$i')b"
+       '
+done
+
+for i in $test_globs_small
+do
+       test_perf "fileglob((a*)^nb) against file (a^100).t; n = $i" '
+               git ls-files "$(cat refglob.'$i')b"
+       '
+done
+
+test_done
index ab4b8b06ae50c5e4ee7e128ded55dea7dddf7865..b6fc880395791c6f33577dc83387939ceb786bbf 100644 (file)
@@ -78,6 +78,10 @@ if test -z "$GIT_PERF_LARGE_REPO"; then
        GIT_PERF_LARGE_REPO=$TEST_DIRECTORY/..
 fi
 
+test_perf_do_repo_symlink_config_ () {
+       test_have_prereq SYMLINKS || git config core.symlinks false
+}
+
 test_perf_create_repo_from () {
        test "$#" = 2 ||
        error "bug in the test script: not 2 parameters to test-create-repo"
@@ -102,15 +106,22 @@ test_perf_create_repo_from () {
        ) &&
        (
                cd "$repo" &&
-               "$MODERN_GIT" init -q && {
-                       test_have_prereq SYMLINKS ||
-                       git config core.symlinks false
-               } &&
+               "$MODERN_GIT" init -q &&
+               test_perf_do_repo_symlink_config_ &&
                mv .git/hooks .git/hooks-disabled 2>/dev/null
        ) || error "failed to copy repository '$source' to '$repo'"
 }
 
 # call at least one of these to establish an appropriately-sized repository
+test_perf_fresh_repo () {
+       repo="${1:-$TRASH_DIRECTORY}"
+       "$MODERN_GIT" init -q "$repo" &&
+       (
+               cd "$repo" &&
+               test_perf_do_repo_symlink_config_
+       )
+}
+
 test_perf_default_repo () {
        test_perf_create_repo_from "${1:-$TRASH_DIRECTORY}" "$GIT_PERF_REPO"
 }