From 1ea3d7fcc4deaf1220a752b2bcb7c9c72270e264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Fri, 5 Nov 2021 15:07:59 +0100 Subject: [PATCH 01/10] command-list.txt: sort with "LC_ALL=C sort" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We should keep these files sorted in the C locale, e.g. in the C locale the order is: git-check-mailmap git-check-ref-format git-checkout But under en_US.UTF-8 it's: git-check-mailmap git-checkout git-check-ref-format In a subsequent commit I'll change generate-cmdlist.sh to use C sort order, and without this change we'd be led to believe that that change caused a meaningful change in the output, so let's do this as a separate step, right now the generate-cmdlist.sh script just uses the order found in this file. Note that this refers to the sort order of the lines in command-list.txt, a subsequent commit will also change how we treat the sort order of the "category" fields, but that's unrelated to this change. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- command-list.txt | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/command-list.txt b/command-list.txt index eb9cee8dee..04cde20c3d 100644 --- a/command-list.txt +++ b/command-list.txt @@ -60,9 +60,9 @@ git-cat-file plumbinginterrogators git-check-attr purehelpers git-check-ignore purehelpers git-check-mailmap purehelpers +git-check-ref-format purehelpers git-checkout mainporcelain git-checkout-index plumbingmanipulators -git-check-ref-format purehelpers git-cherry plumbinginterrogators complete git-cherry-pick mainporcelain git-citool mainporcelain @@ -111,7 +111,6 @@ git-index-pack plumbingmanipulators git-init mainporcelain init git-instaweb ancillaryinterrogators complete git-interpret-trailers purehelpers -gitk mainporcelain git-log mainporcelain info git-ls-files plumbinginterrogators git-ls-remote plumbinginterrogators @@ -124,11 +123,11 @@ git-merge-base plumbinginterrogators git-merge-file plumbingmanipulators git-merge-index plumbingmanipulators git-merge-one-file purehelpers -git-mergetool ancillarymanipulators complete git-merge-tree ancillaryinterrogators -git-multi-pack-index plumbingmanipulators +git-mergetool ancillarymanipulators complete git-mktag plumbingmanipulators git-mktree plumbingmanipulators +git-multi-pack-index plumbingmanipulators git-mv mainporcelain worktree git-name-rev plumbinginterrogators git-notes mainporcelain @@ -154,23 +153,23 @@ git-request-pull foreignscminterface complete git-rerere ancillaryinterrogators git-reset mainporcelain history git-restore mainporcelain worktree -git-revert mainporcelain git-rev-list plumbinginterrogators git-rev-parse plumbinginterrogators +git-revert mainporcelain git-rm mainporcelain worktree git-send-email foreignscminterface complete git-send-pack synchingrepositories +git-sh-i18n purehelpers +git-sh-setup purehelpers git-shell synchelpers git-shortlog mainporcelain git-show mainporcelain info git-show-branch ancillaryinterrogators complete git-show-index plumbinginterrogators git-show-ref plumbinginterrogators -git-sh-i18n purehelpers -git-sh-setup purehelpers git-sparse-checkout mainporcelain -git-stash mainporcelain git-stage complete +git-stash mainporcelain git-status mainporcelain info git-stripspace purehelpers git-submodule mainporcelain @@ -189,7 +188,6 @@ git-var plumbinginterrogators git-verify-commit ancillaryinterrogators git-verify-pack plumbinginterrogators git-verify-tag ancillaryinterrogators -gitweb ancillaryinterrogators git-whatchanged ancillaryinterrogators complete git-worktree mainporcelain git-write-tree plumbingmanipulators @@ -204,6 +202,7 @@ gitfaq guide gitglossary guide githooks guide gitignore guide +gitk mainporcelain gitmailmap guide gitmodules guide gitnamespaces guide @@ -211,6 +210,7 @@ gitremote-helpers guide gitrepository-layout guide gitrevisions guide gitsubmodules guide -gittutorial-2 guide gittutorial guide +gittutorial-2 guide +gitweb ancillaryinterrogators gitworkflows guide From a5bd782982c9e78ed37f3d8227771b798a626e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Fri, 5 Nov 2021 15:08:00 +0100 Subject: [PATCH 02/10] generate-cmdlist.sh: trivial whitespace change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add " " before a "|" at the end of a line in generate-cmdlist.sh for consistency with other code in the file. Some of the surrounding code will be modified in subsequent commits. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- generate-cmdlist.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh index 9dbbb08e70..5114f46680 100755 --- a/generate-cmdlist.sh +++ b/generate-cmdlist.sh @@ -10,7 +10,7 @@ command_list () { } get_categories () { - tr ' ' '\012'| + tr ' ' '\012' | grep -v '^$' | sort | uniq From 191eb491ed44b86c7ab4fe279c8ce47f030624b0 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Fri, 5 Nov 2021 15:08:01 +0100 Subject: [PATCH 03/10] generate-cmdlist.sh: spawn fewer processes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function get_categories() is invoked in a loop over all commands. As it runs several processes, this takes an awful lot of time on Windows. To reduce the number of processes, move the process that filters empty lines to the other invoker of the function, where it is needed. The invocation of get_categories() in the loop does not need the empty line filtered away because the result is word-split by the shell, which eliminates the empty line automatically. Furthermore, use sort -u instead of sort | uniq to remove yet another process. [Ævar: on Linux this seems to speed things up a bit, although with hyperfine(1) the results are fuzzy enough to land within the confidence interval]: $ git show HEAD~:generate-cmdlist.sh >generate-cmdlist.sh.old $ hyperfine --warmup 1 -L s ,.old -p 'make clean' 'sh generate-cmdlist.sh{s} command-list.txt' Benchmark #1: sh generate-cmdlist.sh command-list.txt Time (mean ± σ): 371.3 ms ± 64.2 ms [User: 430.4 ms, System: 72.5 ms] Range (min … max): 320.5 ms … 517.7 ms 10 runs Benchmark #2: sh generate-cmdlist.sh.old command-list.txt Time (mean ± σ): 489.9 ms ± 185.4 ms [User: 724.7 ms, System: 141.3 ms] Range (min … max): 346.0 ms … 885.3 ms 10 runs Summary 'sh generate-cmdlist.sh command-list.txt' ran 1.32 ± 0.55 times faster than 'sh generate-cmdlist.sh.old command-list.txt' Signed-off-by: Johannes Sixt Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- generate-cmdlist.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh index 5114f46680..2736791561 100755 --- a/generate-cmdlist.sh +++ b/generate-cmdlist.sh @@ -11,15 +11,14 @@ command_list () { get_categories () { tr ' ' '\012' | - grep -v '^$' | - sort | - uniq + LC_ALL=C sort -u } category_list () { command_list "$1" | cut -c 40- | - get_categories + get_categories | + grep -v '^$' } get_synopsis () { From 0f05f22516ac8208452e1f2989dfd9adfbb70c3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Fri, 5 Nov 2021 15:08:02 +0100 Subject: [PATCH 04/10] generate-cmdlist.sh: don't call get_categories() from category_list() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This isn't for optimization as the get_categories() is a purely shell function, but rather for ease of readability, let's just inline these two lines. We'll be changing this code some more in subsequent commits to make this worth it. Rename the get_categories() function to get_category_line(), since that's what it's doing now. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- generate-cmdlist.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh index 2736791561..16043e3847 100755 --- a/generate-cmdlist.sh +++ b/generate-cmdlist.sh @@ -9,7 +9,7 @@ command_list () { eval "grep -ve '^#' $exclude_programs" <"$1" } -get_categories () { +get_category_line () { tr ' ' '\012' | LC_ALL=C sort -u } @@ -17,7 +17,8 @@ get_categories () { category_list () { command_list "$1" | cut -c 40- | - get_categories | + tr ' ' '\012' | + LC_ALL=C sort -u | grep -v '^$' } @@ -66,7 +67,7 @@ print_command_list () { while read cmd rest do printf " { \"$cmd\", $(get_synopsis $cmd), 0" - for cat in $(echo "$rest" | get_categories) + for cat in $(echo "$rest" | get_category_line) do printf " | CAT_$cat" done From 48bcd823d43f9aab4d843a4b1004137a96677f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Fri, 5 Nov 2021 15:08:03 +0100 Subject: [PATCH 05/10] generate-cmdlist.sh: run "grep | sort", not "sort | grep" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This doesn't matter for performance, but let's not include the empty lines in our sorting. This makes the intent of the code clearer. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- generate-cmdlist.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh index 16043e3847..e517c33710 100755 --- a/generate-cmdlist.sh +++ b/generate-cmdlist.sh @@ -18,8 +18,8 @@ category_list () { command_list "$1" | cut -c 40- | tr ' ' '\012' | - LC_ALL=C sort -u | - grep -v '^$' + grep -v '^$' | + LC_ALL=C sort -u } get_synopsis () { From 66d55b990ea093be180e816d28143b8952edd52b Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Fri, 5 Nov 2021 15:08:04 +0100 Subject: [PATCH 06/10] generate-cmdlist.sh: replace for loop by printf's auto-repeat feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is just a small code reduction. There is a small probability that the new code breaks when the category list is empty. But that would be noticed during the compile step. Signed-off-by: Johannes Sixt Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- generate-cmdlist.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh index e517c33710..a1ab2b1f07 100755 --- a/generate-cmdlist.sh +++ b/generate-cmdlist.sh @@ -67,10 +67,7 @@ print_command_list () { while read cmd rest do printf " { \"$cmd\", $(get_synopsis $cmd), 0" - for cat in $(echo "$rest" | get_category_line) - do - printf " | CAT_$cat" - done + printf " | CAT_%s" $(echo "$rest" | get_category_line) echo " }," done echo "};" From 8d5be8b421cf525a2fa61cb77921c74be7090c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Fri, 5 Nov 2021 15:08:05 +0100 Subject: [PATCH 07/10] generate-cmdlist.sh: stop sorting category lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In a preceding commit we changed the print_command_list() loop to use printf's auto-repeat feature. Let's now get rid of get_category_line() entirely by not sorting the categories. This will change the output of the generated code from e.g.: - { "git-apply", N_("Apply a patch to files and/or to the index"), 0 | CAT_complete | CAT_plumbingmanipulators }, To: + { "git-apply", N_("Apply a patch to files and/or to the index"), 0 | CAT_plumbingmanipulators | CAT_complete }, I.e. the categories are no longer sorted, but as they're OR'd together it won't matter for the end result. This speeds up the generate-cmdlist.sh a bit. Comparing HEAD~ (old) and "master" to this code: 'sh generate-cmdlist.sh command-list.txt' ran 1.07 ± 0.33 times faster than 'sh generate-cmdlist.sh.old command-list.txt' 1.15 ± 0.36 times faster than 'sh generate-cmdlist.sh.master command-list.txt' Suggested-by: Jeff King Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- generate-cmdlist.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh index a1ab2b1f07..f50112c50f 100755 --- a/generate-cmdlist.sh +++ b/generate-cmdlist.sh @@ -9,11 +9,6 @@ command_list () { eval "grep -ve '^#' $exclude_programs" <"$1" } -get_category_line () { - tr ' ' '\012' | - LC_ALL=C sort -u -} - category_list () { command_list "$1" | cut -c 40- | @@ -67,7 +62,7 @@ print_command_list () { while read cmd rest do printf " { \"$cmd\", $(get_synopsis $cmd), 0" - printf " | CAT_%s" $(echo "$rest" | get_category_line) + printf " | CAT_%s" $rest echo " }," done echo "};" From 3ebeb1d6b10b538b1c1ca05a260e6ad41ea80fd7 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Fri, 5 Nov 2021 15:08:06 +0100 Subject: [PATCH 08/10] generate-cmdlist.sh: do not shell out to "sed" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the "sed" invocation in get_synopsis() with a pure-shell version. This speeds up generate-cmdlist.sh significantly. Compared to HEAD~ (old) and "master" we are, according to hyperfine(1): 'sh generate-cmdlist.sh command-list.txt' ran 12.69 ± 5.01 times faster than 'sh generate-cmdlist.sh.old command-list.txt' 18.34 ± 3.03 times faster than 'sh generate-cmdlist.sh.master command-list.txt' Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- generate-cmdlist.sh | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh index f50112c50f..9b7d6aea62 100755 --- a/generate-cmdlist.sh +++ b/generate-cmdlist.sh @@ -17,16 +17,6 @@ category_list () { LC_ALL=C sort -u } -get_synopsis () { - sed -n ' - /^NAME/,/'"$1"'/H - ${ - x - s/.*'"$1"' - \(.*\)/N_("\1")/ - p - }' "Documentation/$1.txt" -} - define_categories () { echo echo "/* Command categories */" @@ -61,7 +51,18 @@ print_command_list () { command_list "$1" | while read cmd rest do - printf " { \"$cmd\", $(get_synopsis $cmd), 0" + synopsis= + while read line + do + case "$line" in + "$cmd - "*) + synopsis=${line#$cmd - } + break + ;; + esac + done <"Documentation/$cmd.txt" + + printf '\t{ "%s", N_("%s"), 0' "$cmd" "$synopsis" printf " | CAT_%s" $rest echo " }," done From e88842ee1c81d45157e2a4e87f6065b6837e279a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Fri, 5 Nov 2021 15:08:07 +0100 Subject: [PATCH 09/10] generate-cmdlist.sh: replace "grep' invocation with a shell version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the "grep" we run to exclude certain programs from the generated output with a pure-shell loop that strips out the comments, and sees if the "cmd" we're reading is on a list of excluded programs. This uses a trick similar to test_have_prereq() in test-lib-functions.sh. On my *nix system this makes things quite a bit slower compared to HEAD~: o 'sh generate-cmdlist.sh.old command-list.txt' ran 1.56 ± 0.11 times faster than 'sh generate-cmdlist.sh command-list.txt' 18.00 ± 0.19 times faster than 'sh generate-cmdlist.sh.master command-list.txt' But when I tried running generate-cmdlist.sh 100 times in CI I found that it helped across the board even on OSX & Linux. I tried testing it in CI with this ad-hoc few-liner: for i in $(seq -w 0 11 | sort -nr) do git show HEAD~$i:generate-cmdlist.sh >generate-cmdlist-HEAD$i.sh && git add generate-cmdlist* && cp t/t0000-generate-cmdlist.sh t/t00$i-generate-cmdlist.sh || : && perl -pi -e "s/HEAD0/HEAD$i/g" t/t00$i-generate-cmdlist.sh && git add t/t00*.sh done && git commit -m"generated it" Here HEAD~02 and the t0002* file refers to this change, and HEAD~03 and t0003* file to the preceding commit, the relevant results were: linux-gcc: [12:05:33] t0002-generate-cmdlist.sh .. ok 14 ms ( 0.00 usr 0.00 sys + 3.64 cusr 3.09 csys = 6.73 CPU) [12:05:30] t0003-generate-cmdlist.sh .. ok 32 ms ( 0.00 usr 0.00 sys + 2.66 cusr 1.81 csys = 4.47 CPU) osx-gcc: [11:58:04] t0002-generate-cmdlist.sh .. ok 80081 ms ( 0.02 usr 0.02 sys + 17.80 cusr 10.07 csys = 27.91 CPU) [11:58:16] t0003-generate-cmdlist.sh .. ok 92127 ms ( 0.02 usr 0.01 sys + 22.54 cusr 14.27 csys = 36.84 CPU) vs-test: [12:03:14] t0002-generate-cmdlist.sh .. ok 30 s ( 0.02 usr 0.00 sys + 13.14 cusr 26.19 csys = 39.35 CPU) [12:03:20] t0003-generate-cmdlist.sh .. ok 32 s ( 0.00 usr 0.02 sys + 13.25 cusr 26.10 csys = 39.37 CPU) I.e. even on *nix running 100 of these in a loop was up to ~2x faster in absolute runtime, I suspect it's due factors that are exacerbated in the CI, e.g. much slower process startup due to some platform limits, or a slower FS. The "cut -d" change here is because we're not emitting the 40-character aligned output anymore, i.e. we'll get the output from command_list() now, not an as-is line from command-list.txt. This also makes the parsing more reliable, as we could tweak the whitespace alignment without breaking this parser. Let's reword a now-inaccurate comment in "command-list.txt" describing that previous alignment limitation. We'll still need the "### command-list [...]" line due to the "Documentation/cmd-list.perl" logic added in 11c6659d85d (command-list: prepare machinery for upcoming "common groups" section, 2015-05-21). There was a proposed change subsequent to this one[3] which continued moving more logic into the "command_list() function, i.e. replaced the "cut | tr | grep" chain in "category_list()" with an argument to "command_list()". That change might have had a bit of an effect, but not as much as the preceding commit, so I decided to drop it. The relevant performance numbers from it were: linux-gcc: [12:05:33] t0001-generate-cmdlist.sh .. ok 13 ms ( 0.00 usr 0.00 sys + 3.33 cusr 2.78 csys = 6.11 CPU) [12:05:33] t0002-generate-cmdlist.sh .. ok 14 ms ( 0.00 usr 0.00 sys + 3.64 cusr 3.09 csys = 6.73 CPU) osx-gcc: [11:58:03] t0001-generate-cmdlist.sh .. ok 78416 ms ( 0.02 usr 0.01 sys + 11.78 cusr 6.22 csys = 18.03 CPU) [11:58:04] t0002-generate-cmdlist.sh .. ok 80081 ms ( 0.02 usr 0.02 sys + 17.80 cusr 10.07 csys = 27.91 CPU) vs-test: [12:03:20] t0001-generate-cmdlist.sh .. ok 34 s ( 0.00 usr 0.03 sys + 12.42 cusr 19.55 csys = 32.00 CPU) [12:03:14] t0002-generate-cmdlist.sh .. ok 30 s ( 0.02 usr 0.00 sys + 13.14 cusr 26.19 csys = 39.35 CPU) As above HEAD~2 and t0002* are testing the code in this commit (and the line is the same), but HEAD~1 and t0001* are testing that dropped change in [3]. 1. https://lore.kernel.org/git/cover-v2-00.10-00000000000-20211022T193027Z-avarab@gmail.com/ 2. https://lore.kernel.org/git/patch-v2-08.10-83318d6c0da-20211022T193027Z-avarab@gmail.com/ 3. https://lore.kernel.org/git/patch-v2-10.10-e10a43756d1-20211022T193027Z-avarab@gmail.com/ Signed-off-by: Junio C Hamano --- command-list.txt | 2 +- generate-cmdlist.sh | 24 ++++++++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/command-list.txt b/command-list.txt index 04cde20c3d..675c28f0bd 100644 --- a/command-list.txt +++ b/command-list.txt @@ -43,7 +43,7 @@ # specified here, which can only have "guide" attribute and nothing # else. # -### command list (do not change this line, also do not change alignment) +### command list (do not change this line) # command name category [category] [category] git-add mainporcelain worktree git-am mainporcelain diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh index 9b7d6aea62..cfe0454d1d 100755 --- a/generate-cmdlist.sh +++ b/generate-cmdlist.sh @@ -6,12 +6,28 @@ die () { } command_list () { - eval "grep -ve '^#' $exclude_programs" <"$1" + while read cmd rest + do + case "$cmd" in + "#"* | '') + # Ignore comments and allow empty lines + continue + ;; + *) + case "$exclude_programs" in + *":$cmd:"*) + ;; + *) + echo "$cmd $rest" + ;; + esac + esac + done <"$1" } category_list () { command_list "$1" | - cut -c 40- | + cut -d' ' -f2- | tr ' ' '\012' | grep -v '^$' | LC_ALL=C sort -u @@ -69,11 +85,11 @@ print_command_list () { echo "};" } -exclude_programs= +exclude_programs=: while test "--exclude-program" = "$1" do shift - exclude_programs="$exclude_programs -e \"^$1 \"" + exclude_programs="$exclude_programs$1:" shift done From 1cecd06e36452bfb8d074cda2083cc71ff089404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Fri, 5 Nov 2021 15:08:08 +0100 Subject: [PATCH 10/10] generate-cmdlist.sh: don't parse command-list.txt thrice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change the "define_categories()" and "define_category_names()" functions to take the already-parsed output of "category_list()" as an argument, which brings our number of passes over "command-list.txt" from three to two. Then have "category_list()" itself take the output of "command_list()" as an argument, bringing the number of times we parse the file to one. Compared to the pre-image this speeds us up quite a bit: $ git show HEAD~:generate-cmdlist.sh >generate-cmdlist.sh.old $ hyperfine --warmup 10 -L v ,.old 'sh generate-cmdlist.sh{v} command-list.txt' Benchmark #1: sh generate-cmdlist.sh command-list.txt Time (mean ± σ): 22.9 ms ± 0.3 ms [User: 15.8 ms, System: 9.6 ms] Range (min … max): 22.5 ms … 24.0 ms 125 runs Benchmark #2: sh generate-cmdlist.sh.old command-list.txt Time (mean ± σ): 30.1 ms ± 0.4 ms [User: 24.4 ms, System: 17.5 ms] Range (min … max): 29.5 ms … 32.3 ms 96 runs Summary 'sh generate-cmdlist.sh command-list.txt' ran 1.32 ± 0.02 times faster than 'sh generate-cmdlist.sh.old command-list.txt' Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- generate-cmdlist.sh | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh index cfe0454d1d..205541e0f7 100755 --- a/generate-cmdlist.sh +++ b/generate-cmdlist.sh @@ -26,7 +26,7 @@ command_list () { } category_list () { - command_list "$1" | + echo "$1" | cut -d' ' -f2- | tr ' ' '\012' | grep -v '^$' | @@ -37,7 +37,7 @@ define_categories () { echo echo "/* Command categories */" bit=0 - category_list "$1" | + echo "$1" | while read cat do echo "#define CAT_$cat (1UL << $bit)" @@ -51,7 +51,7 @@ define_category_names () { echo "/* Category names */" echo "static const char *category_names[] = {" bit=0 - category_list "$1" | + echo "$1" | while read cat do echo " \"$cat\", /* (1UL << $bit) */" @@ -64,7 +64,7 @@ define_category_names () { print_command_list () { echo "static struct cmdname_help command_list[] = {" - command_list "$1" | + echo "$1" | while read cmd rest do synopsis= @@ -93,6 +93,9 @@ do shift done +commands="$(command_list "$1")" +categories="$(category_list "$commands")" + echo "/* Automatically generated by generate-cmdlist.sh */ struct cmdname_help { const char *name; @@ -100,8 +103,8 @@ struct cmdname_help { uint32_t category; }; " -define_categories "$1" +define_categories "$categories" echo -define_category_names "$1" +define_category_names "$categories" echo -print_command_list "$1" +print_command_list "$commands"