summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmethyst Reese <amethyst@n7.gg>2024-03-01 10:52:53 (GMT)
committerGitHub <noreply@github.com>2024-03-01 10:52:53 (GMT)
commit4a630980328b67f0aba6a04c3950aa9dbd532895 (patch)
tree5dcd78b09e4967f71482ecdd4de9ed50eaa21038
parent7b4794319c56b6b00e852c745af50fd95bd1a550 (diff)
downloadcpython-4a630980328b67f0aba6a04c3950aa9dbd532895.zip
cpython-4a630980328b67f0aba6a04c3950aa9dbd532895.tar.gz
cpython-4a630980328b67f0aba6a04c3950aa9dbd532895.tar.bz2
gh-116159: argparse: performance improvement parsing large number of options (#116162)
When parsing positional vs optional arguments, the use of min with a list comprehension inside of a loop results in quadratic time based on the number of optional arguments given. When combined with use of prefix based argument files and a large number of optional flags, this can result in extremely slow parsing behavior. This replaces the min call with a simple loop with a short circuit to break at the next optional argument. Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>
-rw-r--r--Lib/argparse.py9
1 files changed, 5 insertions, 4 deletions
diff --git a/Lib/argparse.py b/Lib/argparse.py
index 4200dd5..0dbdd67 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -2153,10 +2153,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
while start_index <= max_option_string_index:
# consume any Positionals preceding the next option
- next_option_string_index = min([
- index
- for index in option_string_indices
- if index >= start_index])
+ next_option_string_index = start_index
+ while next_option_string_index <= max_option_string_index:
+ if next_option_string_index in option_string_indices:
+ break
+ next_option_string_index += 1
if start_index != next_option_string_index:
positionals_end_index = consume_positionals(start_index)