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>
This commit is contained in:
Amethyst Reese 2024-03-01 02:52:53 -08:00 committed by GitHub
parent 7b4794319c
commit 4a63098032
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 5 additions and 4 deletions

View File

@ -2153,10 +2153,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
while start_index <= max_option_string_index: while start_index <= max_option_string_index:
# consume any Positionals preceding the next option # consume any Positionals preceding the next option
next_option_string_index = min([ next_option_string_index = start_index
index while next_option_string_index <= max_option_string_index:
for index in option_string_indices if next_option_string_index in option_string_indices:
if index >= start_index]) break
next_option_string_index += 1
if start_index != next_option_string_index: if start_index != next_option_string_index:
positionals_end_index = consume_positionals(start_index) positionals_end_index = consume_positionals(start_index)