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

Feature: 优化依赖注入在 pydantic v2 下的性能 #2870

Merged
merged 2 commits into from
Aug 11, 2024

Conversation

yanyongyu
Copy link
Member

@yanyongyu yanyongyu commented Aug 11, 2024

缓存 pydantic 的 TypeAdapter 来避免高耗时的类型分析。

fix #2841

performance before:
result.json
image

performance after:
result_new.json
image

Benchmark Code

benchmark code:

from typing import Any

from nonebot.adapters import Bot, Event
from nonebot.dependencies import Dependent
from nonebot.internal.adapter.message import Message
from nonebot.params import Depends, BotParam, EventParam, DependParam


class FakeBot(Bot):
    async def send(self, event: Event, message, **kwargs: Any) -> Any: ...


class FakeEvent(Event):
    def get_type(self) -> str: ...

    def get_event_name(self) -> str: ...

    def get_event_description(self) -> str: ...

    def get_user_id(self) -> str: ...

    def get_session_id(self) -> str: ...

    def get_message(self) -> Message: ...

    def is_tome(self) -> bool: ...


async def dep():
    return {"test": 1}


async def test(bot: Bot, event: Event, data: dict[str, int] = Depends(dep)): ...


async def main():
    parsed = Dependent[None].parse(
        call=test, allow_types=(BotParam, EventParam, DependParam)
    )

    await asyncio.gather(
        *(parsed(bot=FakeBot(1, "1"), event=FakeEvent()) for _ in range(10000))  # type: ignore
    )


if __name__ == "__main__":
    import asyncio

    asyncio.run(main())

run with py-spy record -o result.json --format speedscope -- python bench.py

@yanyongyu yanyongyu added the enhancement New feature or request label Aug 11, 2024
Copy link

codecov bot commented Aug 11, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 94.22%. Comparing base (26eabfa) to head (da65268).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2870      +/-   ##
==========================================
+ Coverage   94.18%   94.22%   +0.03%     
==========================================
  Files          48       48              
  Lines        4041     4051      +10     
==========================================
+ Hits         3806     3817      +11     
+ Misses        235      234       -1     
Flag Coverage Δ
unittests 94.22% <100.00%> (+0.03%) ⬆️

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

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

🚀 Deployed to https://deploy-preview-2870--nonebot2.netlify.app

@yanyongyu yanyongyu merged commit b59b1be into master Aug 11, 2024
43 checks passed
@yanyongyu yanyongyu deleted the feat/improve-pydantic-performance branch August 11, 2024 07:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

Successfully merging this pull request may close these issues.

Feature: 优化 pydantic validation 流程
3 participants