New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
new improved CallableMixin #1357
Conversation
✔️ Changelog found.Thank you for adding a description of the changes |
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## dev-3.x #1357 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 369 369
Lines 9444 9447 +3
=========================================
+ Hits 9444 9447 +3
Flags with carried forward coverage won't be shown. Click here to find out more.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you have a performance test and comparison of results, so please post that test and results as a comment to this pull request.
This can help advanced users understand what has actually been changed.
Co-authored-by: Oleg A. <t0rr@mail.ru>
from typing import Set, Dict, Any
import matplotlib.pyplot as plt
from aiogram.dispatcher.event.handler import CallableMixin, CallbackType
from dataclasses import field, dataclass
import inspect
from timeit import timeit
@dataclass
class CallableMixinEX:
callback: CallbackType
awaitable: bool = field(init=False)
params: Set[str] = field(init=False)
varkw: bool = field(init=False)
def post_init(self) -> None:
callback = inspect.unwrap(self.callback)
self.awaitable = inspect.isawaitable(callback) or inspect.iscoroutinefunction(callback)
spec = inspect.getfullargspec(callback)
self.params = {*spec.args, *spec.kwonlyargs}
self.varkw = spec.varkw is not None
def _prepare_kwargs(self, kwargs: Dict[str, Any]) -> Dict[str, Any]:
if self.varkw:
return kwargs
return {k: kwargs[k] for k in self.params if k in kwargs}
REPEAT = 1000000
MAX_FUNC_PARAMS = 10
MAX_MIDDLEWARE_DATA = MAX_FUNC_PARAMS + 5
KEYS = tuple(f"param_{i}" for i in range(MAX_MIDDLEWARE_DATA))
X = []
X_EX = []
Y = []
for FUNC_PARAMS_SIZE in range(1, MAX_FUNC_PARAMS):
PARAMS = ", ".join(KEYS[:FUNC_PARAMS_SIZE])
FUNC = eval(f"lambda {PARAMS}: 1")
for MIDDLEWARE_SIZE in range(FUNC_PARAMS_SIZE, MAX_MIDDLEWARE_DATA):
MIDDLEWARE_DATA = dict(zip(KEYS[:MIDDLEWARE_SIZE], range(MIDDLEWARE_SIZE)))
X.append(timeit(
stmt="call._prepare_kwargs(MIDDLEWARE_DATA)",
setup="call = CallableMixin(FUNC)",
globals={**globals(), **locals()},
number=REPEAT
))
X_EX.append(timeit(
stmt="call._prepare_kwargs(MIDDLEWARE_DATA)",
setup="call = CallableMixinEX(FUNC)",
globals={**globals(), **locals()},
number=REPEAT
))
Y.append(f"{FUNC_PARAMS_SIZE}x{MIDDLEWARE_SIZE}")
plt.plot(Y, X)
plt.plot(Y, X_EX)
plt.xlabel('func param size x middleware data size')
plt.ylabel('time, [s]')
plt.grid()
plt.xticks(rotation=-90)
plt.legend(['old', 'new'])
plt.show() |
Description
new improved CallableMixin
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
all internal aiogram tests
Checklist: