Skip to content
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

Merged
merged 4 commits into from Nov 13, 2023
Merged

new improved CallableMixin #1357

merged 4 commits into from Nov 13, 2023

Conversation

RootShinobi
Copy link
Contributor

@RootShinobi RootShinobi commented Nov 4, 2023

Description

new improved CallableMixin

Type of change

Please delete options that are not relevant.

  • Documentation (typos, code examples or any documentation update)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

all internal aiogram tests

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@github-actions github-actions bot added the 3.x Issue or PR for stable 3.x version label Nov 4, 2023
Copy link

github-actions bot commented Nov 4, 2023

✔️ Changelog found.

Thank you for adding a description of the changes

Copy link

codecov bot commented Nov 4, 2023

Codecov Report

Merging #1357 (cb68bb2) into dev-3.x (a355dab) will not change coverage.
Report is 1 commits behind head on dev-3.x.
The diff coverage is 100.00%.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##           dev-3.x     #1357   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          369       369           
  Lines         9444      9447    +3     
=========================================
+ Hits          9444      9447    +3     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
aiogram/dispatcher/event/handler.py 100.00% <100.00%> (ø)

Copy link
Member

@JrooTJunior JrooTJunior left a 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.

CHANGES/1357.misc.rst Outdated Show resolved Hide resolved
@JrooTJunior JrooTJunior added the enhancement Make it better! label Nov 6, 2023
CHANGES/1357.misc.rst Outdated Show resolved Hide resolved
Co-authored-by: Oleg A. <t0rr@mail.ru>
@RootShinobi
Copy link
Contributor Author

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.

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()

photo

@JrooTJunior JrooTJunior merged commit e76f4c3 into aiogram:dev-3.x Nov 13, 2023
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.x Issue or PR for stable 3.x version enhancement Make it better!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants