[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Quilt-dev] [PATCH 1/2] patches: Performance boost on large series
From: |
Jean Delvare |
Subject: |
[Quilt-dev] [PATCH 1/2] patches: Performance boost on large series |
Date: |
Wed, 24 Jul 2024 18:35:27 +0200 |
User-agent: |
Evolution 3.42.4 |
On large series, the patches command is horribly slow. This is caused
by a performance issue in bash 4.4 and older when a function with a
lot of positional parameters calls another function.
This can be worked around by expanding the list of patches inside the
functions instead of passing them as parameters. In my tests, this
speeds up the command by a factor 1000 (from over 34 minutes to 2
seconds on a fully applied 48000 patch series).
Signed-off-by: Jean Delvare <jdelvare@suse.de>
---
quilt/patches.in | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
--- a/quilt/patches.in
+++ b/quilt/patches.in
@@ -29,14 +29,17 @@ Note that this heuristic is much slower
fi
}
-# Uses global variable opt_files
+# Uses global variables top and opt_files
scan_applied()
{
local color=$1 prefix=$2
- shift 2
local patch file
+ local -a patch_list
- for patch in "$@"
+ eval "patch_list=( $3 )"
+ set --
+
+ for patch in "${patch_list[@]}"
do
for file in "${opt_files[@]}"
do
@@ -49,13 +52,15 @@ scan_applied()
done
}
-# Uses global variable opt_files
+# Uses global variables top and opt_files
scan_unapplied()
{
local color=$1 prefix=$2
- shift 2
local patch file
- local -a files_bre
+ local -a patch_list files_bre
+
+ eval "patch_list=( $3 )"
+ set --
# Quote each file name only once
for file in "${opt_files[@]}"
@@ -66,7 +71,7 @@ scan_unapplied()
# "Or" all files in a single pattern
file=\\\($(array_join \\\| "${files_bre[@]}")\\\)
- for patch in "$@"
+ for patch in "${patch_list[@]}"
do
if filenames_in_patch "$patch" \
| grep -q "^$file\$"
@@ -148,15 +153,19 @@ fi
setup_pager
+# bash 4.4 and earlier perform poorly when a huge number of parameters
+# are passed to a function which in turn calls another function. We use
+# eval as a workaround, so the patch list is generated locally instead
+# of being passed as parameters.
if [ -n "$top" ]
then
scan_applied "$color_series_app" "$applied" \
- $(applied_before $top)
+ '$(applied_before $top)'
scan_applied "$color_series_top" "$current" \
- $top
+ '$top'
fi
scan_unapplied "$color_series_una" "$unapplied" \
- $(patches_after $top)
+ '$(patches_after $top)'
### Local Variables:
### mode: shell-script
### End:
--
Jean Delvare
SUSE L3 Support
- [Quilt-dev] [PATCH 1/2] patches: Performance boost on large series,
Jean Delvare <=