diff --git a/.gitignore b/.gitignore index 434740e..032cc69 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -.venv +.venv*/ *.py[co] __pycache__ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..3ab1f96 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Current File", + "type": "python", + "request": "launch", + "program": "suite.py", + "console": "integratedTerminal", + "justMyCode": true + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index a7357aa..69059f3 100644 --- a/README.md +++ b/README.md @@ -12,20 +12,26 @@ $ python suite.py ## Results ```default -┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ -┃ Pattern ┃ Benchmark ┃ Repe… ┃ Min ┃ Max ┃ Mean ┃ Min (+) ┃ Max (+) ┃ Mean (+) ┃ -┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩ -│ 1 │ Copy slice to Local │ 25 │ 0.221 │ 0.224 │ 0.222 │ 0.165 (25.4%) │ 0.169 (24.3%) │ 0.166 (25.2%) │ -│ 2 │ Copy name to Local │ 25 │ 0.124 │ 0.127 │ 0.126 │ 0.098 (21.1%) │ 0.099 (22.2%) │ 0.099 (21.7%) │ -│ 3 │ Copy dict item to Local │ 25 │ 0.254 │ 0.256 │ 0.255 │ 0.097 (61.9%) │ 0.098 (61.7%) │ 0.097 (61.9%) │ -│ 4 │ Copy class attr to Local │ 25 │ 0.222 │ 0.230 │ 0.225 │ 0.075 (66.1%) │ 0.077 (66.7%) │ 0.076 (66.1%) │ -│ 5 │ Importing specific name instead of namespace │ 25 │ 0.000 │ 0.000 │ 0.000 │ 0.000 (4.5%) │ 0.000 (34.1%) │ 0.000 (14.1%) │ -│ 6 │ Slicing with memoryview instead of bytes │ 25 │ 0.001 │ 0.001 │ 0.001 │ 0.001 (36.3%) │ 0.001 (33.7%) │ 0.001 (35.6%) │ -│ 7 │ **Kwargs for known keyword args │ 25 │ 0.000 │ 0.000 │ 0.000 │ 0.000 (15.1%) │ 0.000 (19.2%) │ 0.000 (17.3%) │ -│ 8 │ Tiny Functions │ 25 │ 0.000 │ 0.000 │ 0.000 │ 0.000 (71.5%) │ 0.000 (68.5%) │ 0.000 (69.7%) │ -│ 9 │ Class instead of dataclass │ 25 │ 0.016 │ 0.016 │ 0.016 │ 0.005 (70.9%) │ 0.005 (70.2%) │ 0.005 (70.4%) │ -│ 10 │ Namedtuple instead of dataclass │ 25 │ 0.015 │ 0.016 │ 0.016 │ 0.006 (58.2%) │ 0.007 (56.9%) │ 0.007 (57.5%) │ -│ 11 │ class instead of namedtuple │ 25 │ 0.006 │ 0.007 │ 0.007 │ 0.005 (28.0%) │ 0.005 (30.1%) │ 0.005 (29.1%) │ -│ 12 │ dict instead of class │ 25 │ 0.005 │ 0.005 │ 0.005 │ 0.003 (31.7%) │ 0.004 (30.6%) │ 0.003 (32.9%) │ -└─────────┴──────────────────────────────────────────────┴───────┴─────────┴─────────┴─────────┴─────────────────┴─────────────────┴─────────────────┘ + Anti-Pattern Benchmark Suite, repeat=5, number=5 +┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ +┃ Pattern ┃ Benchmark ┃ ┃ Min ┃ Max ┃ Mean ┃ Min (+) ┃ Max (+) ┃ Mean (+) ┃ +┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩ +│ 1 │ Copy slice to Local │ │ 0.200 │ 0.230 │ 0.209 │ 0.132 (33.8%) │ 0.224 (2.7%) │ 0.156 (25.4%) │ +│ 2 │ Copy name to Local │ │ 0.117 │ 0.130 │ 0.122 │ 0.084 (28.3%) │ 0.089 (31.5%) │ 0.086 (29.6%) │ +│ 3 │ Copy dict item to Local │ │ 0.184 │ 0.257 │ 0.219 │ 0.085 (53.9%) │ 0.092 (64.1%) │ 0.088 (59.7%) │ +│ 4 │ Copy class attr to Local │ │ 0.146 │ 0.149 │ 0.148 │ 0.058 (60.0%) │ 0.060 (59.7%) │ 0.059 (59.9%) │ +│ 5 │ Importing specific name instead of namespace │ │ 0.000 │ 0.000 │ 0.000 │ 0.000 (2.9%) │ 0.000 (40.4%) │ 0.000 (15.7%) │ +│ 6 │ Slicing with memoryview instead of bytes │ │ 0.001 │ 0.001 │ 0.001 │ 0.000 (40.0%) │ 0.001 (23.0%) │ 0.001 (34.9%) │ +│ 7 │ **Kwargs for known keyword args │ │ 0.000 │ 0.000 │ 0.000 │ 0.000 (38.1%) │ 0.000 (29.9%) │ 0.000 (35.2%) │ +│ 8 │ Tiny Functions │ │ 0.000 │ 0.000 │ 0.000 │ 0.000 (60.7%) │ 0.000 (55.8%) │ 0.000 (58.6%) │ +│ 9 │ Class instead of dataclass │ │ 0.548 │ 0.654 │ 0.596 │ 0.279 (49.0%) │ 0.306 (53.1%) │ 0.295 (50.4%) │ +│ 10 │ Namedtuple instead of dataclass │ │ 0.556 │ 0.648 │ 0.578 │ 0.394 (29.0%) │ 0.539 (16.7%) │ 0.432 (25.2%) │ +│ 11 │ class instead of namedtuple │ │ 0.433 │ 0.516 │ 0.465 │ 0.293 (32.3%) │ 0.315 (39.0%) │ 0.303 (34.9%) │ +│ 12 │ namedtuple class instead of namedtuple │ │ 0.383 │ 0.392 │ 0.387 │ 0.395 (-3.2%) │ 0.422 (-7.6%) │ 0.405 (-4.8%) │ +│ 13 │ dict instead of class │ │ 0.288 │ 0.307 │ 0.294 │ 0.318 (-10.6%) │ 0.375 (-22.1%) │ 0.345 (-17.3%) │ +│ 14 │ class with slots │ │ 0.327 │ 0.427 │ 0.360 │ 0.257 (21.4%) │ 0.298 (30.3%) │ 0.275 (23.7%) │ +│ 15 │ dataclass with slots │ │ 0.561 │ 0.611 │ 0.593 │ 0.523 (6.8%) │ 0.588 (3.7%) │ 0.552 (7.0%) │ +│ 16 │ Using a list comprehension to filter another list │ │ 0.029 │ 0.030 │ 0.029 │ 0.022 (24.7%) │ 0.025 (14.8%) │ 0.023 (21.6%) │ +│ 17 │ Refactoring Try..except outside a loop │ │ 0.020 │ 0.020 │ 0.020 │ 0.018 (11.0%) │ 0.019 (8.4%) │ 0.018 (10.6%) │ +└─────────┴───────────────────────────────────────────────────┴──┴─────────┴─────────┴─────────┴─────────────────┴─────────────────┴─────────────────┘ ``` diff --git a/dummy/__init__.py b/dummy/__init__.py new file mode 100644 index 0000000..fa4382f --- /dev/null +++ b/dummy/__init__.py @@ -0,0 +1,6 @@ +print("hello") + +def foo(): + pass + +CONST = 123 \ No newline at end of file diff --git a/dummy/example.py b/dummy/example.py new file mode 100644 index 0000000..43fca2a --- /dev/null +++ b/dummy/example.py @@ -0,0 +1,29 @@ +from typing import Generator, Union + +__all__ = ("main1", "main2") + +def main1() -> Union[str, bytes]: + return 'hello world' + + +def main2() -> Generator[Union[str, bytes], None, int]: + yield "hello" + yield " " + yield "world" + return 123 # size of response + +def is_generator(co): + return co.__code__.co_flags & 32 + + +test_functions = [main1, main2] + +for f in test_functions: + response: str = '' + if is_generator(f): + for part in f(): + response += part + else: + response = f() + + print(response)