-
-
Notifications
You must be signed in to change notification settings - Fork 178
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
argparse
benchmarks for subparsers and many optionals (#367)
* Add argparse benchmark * Add benchmark for testing lots of args * Reorder in MANIFEST * Fix formatting * Add newline * Formatting * Update description * Formatting...again * Update docstring * Attempting to fix the tests * Remove line * Refactor into single run_benchmark * Add newline; * Remove extraneous files * Formatting :)
- Loading branch information
1 parent
ebc5013
commit f113ee3
Showing
4 changed files
with
147 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
pyperformance/data-files/benchmarks/bm_argparse/bm_argparse_subparsers.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[project] | ||
name = "pyperformance_bm_argparse" | ||
requires-python = ">=3.8" | ||
dependencies = ["pyperf"] | ||
urls = {repository = "https://github.com/python/pyperformance"} | ||
dynamic = ["version"] | ||
|
||
[tool.pyperformance] | ||
name = "argparse_subparsers" | ||
extra_opts = ["subparsers"] |
10 changes: 10 additions & 0 deletions
10
pyperformance/data-files/benchmarks/bm_argparse/pyproject.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[project] | ||
name = "pyperformance_bm_argparse" | ||
requires-python = ">=3.8" | ||
dependencies = ["pyperf"] | ||
urls = {repository = "https://github.com/python/pyperformance"} | ||
dynamic = ["version"] | ||
|
||
[tool.pyperformance] | ||
name = "argparse_many_optionals" | ||
extra_opts = ["many_optionals"] |
125 changes: 125 additions & 0 deletions
125
pyperformance/data-files/benchmarks/bm_argparse/run_benchmark.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
""" | ||
Benchmark argparse programs with: | ||
1) multiple subparsers, each with their own subcommands, and then parse a series of command-line arguments. | ||
2) a large number of optional arguments, and then parse a series of command-line arguments. | ||
Author: Savannah Ostrowski | ||
""" | ||
|
||
import argparse | ||
import pyperf | ||
|
||
|
||
def generate_arguments(i: int) -> list: | ||
arguments = ["input.txt", "output.txt"] | ||
for i in range(i): | ||
arguments.extend([f"--option{i}", f"value{i}"]) | ||
return arguments | ||
|
||
|
||
def bm_many_optionals() -> argparse.ArgumentParser: | ||
parser = argparse.ArgumentParser(description="A version control system CLI") | ||
|
||
parser.add_argument("--version", action="version", version="1.0") | ||
|
||
subparsers = parser.add_subparsers(dest="command", required=True) | ||
|
||
add_parser = subparsers.add_parser("add", help="Add a file to the repository") | ||
add_parser.add_argument("files", nargs="+", help="List of files to add to staging") | ||
|
||
commit_parser = subparsers.add_parser( | ||
"commit", help="Commit changes to the repository" | ||
) | ||
commit_parser.add_argument("-m", "--message", required=True, help="Commit message") | ||
|
||
commit_group = commit_parser.add_mutually_exclusive_group(required=False) | ||
commit_group.add_argument( | ||
"--amend", action="store_true", help="Amend the last commit" | ||
) | ||
commit_group.add_argument( | ||
"--no-edit", action="store_true", help="Reuse the last commit message" | ||
) | ||
|
||
push_parser = subparsers.add_parser( | ||
"push", help="Push changes to remote repository" | ||
) | ||
|
||
network_group = push_parser.add_argument_group("Network options") | ||
network_group.add_argument("--dryrun", action="store_true", help="Simulate changes") | ||
network_group.add_argument( | ||
"--timeout", type=int, default=30, help="Timeout in seconds" | ||
) | ||
|
||
auth_group = push_parser.add_argument_group("Authentication options") | ||
auth_group.add_argument( | ||
"--username", required=True, help="Username for authentication" | ||
) | ||
auth_group.add_argument( | ||
"--password", required=True, help="Password for authentication" | ||
) | ||
|
||
global_group = parser.add_mutually_exclusive_group() | ||
global_group.add_argument("--verbose", action="store_true", help="Verbose output") | ||
global_group.add_argument("--quiet", action="store_true", help="Quiet output") | ||
|
||
argument_lists = [ | ||
["--verbose", "add", "file1.txt", "file2.txt"], | ||
["add", "file1.txt", "file2.txt"], | ||
["commit", "-m", "Initial commit"], | ||
["commit", "-m", "Add new feature", "--amend"], | ||
[ | ||
"push", | ||
"--dryrun", | ||
"--timeout", | ||
"60", | ||
"--username", | ||
"user", | ||
"--password", | ||
"pass", | ||
], | ||
] | ||
|
||
for arguments in argument_lists: | ||
parser.parse_args(arguments) | ||
|
||
|
||
def bm_subparsers() -> argparse.ArgumentParser: | ||
parser = argparse.ArgumentParser() | ||
|
||
parser.add_argument("input_file", type=str, help="The input file") | ||
parser.add_argument("output_file", type=str, help="The output file") | ||
|
||
for i in range(1000): | ||
parser.add_argument(f"--option{i}", type=str, help=f"Optional argument {i}") | ||
|
||
argument_lists = [ | ||
generate_arguments(500), | ||
generate_arguments(1000), | ||
] | ||
|
||
for args in argument_lists: | ||
parser.parse_args(args) | ||
|
||
|
||
BENCHMARKS = { | ||
"many_optionals": bm_many_optionals, | ||
"subparsers": bm_subparsers, | ||
} | ||
|
||
|
||
def add_cmdline_args(cmd, args): | ||
cmd.append(args.benchmark) | ||
|
||
|
||
def add_parser_args(parser): | ||
parser.add_argument("benchmark", choices=BENCHMARKS, help="Which benchmark to run.") | ||
|
||
|
||
if __name__ == "__main__": | ||
runner = pyperf.Runner(add_cmdline_args=add_cmdline_args) | ||
runner.metadata["description"] = "Argparse benchmark" | ||
add_parser_args(runner.argparser) | ||
args = runner.parse_args() | ||
benchmark = args.benchmark | ||
|
||
runner.bench_func(args.benchmark, BENCHMARKS[args.benchmark]) |