Skip to content

Avoid exceptions when resolving hooks on schema class creation - #3111

Open
deadstrobe5 wants to merge 2 commits into
marshmallow-code:devfrom
deadstrobe5:perf/resolve-hooks-no-exc
Open

deadstrobe5 wants to merge 2 commits into
marshmallow-code:devfrom
deadstrobe5:perf/resolve-hooks-no-exc

Conversation

@deadstrobe5

Copy link
Copy Markdown

SchemaMeta.resolve_hooks looks at every attribute name in dir(cls). For each one it finds the defining class with try: parent.__dict__[attr_name] except KeyError and then checks attr.__marshmallow_hook__ with try/except AttributeError. Almost no attribute is a hook, so creating a schema class with 2 fields raises and catches about 145 exceptions. This uses attr_name in parent.__dict__ and getattr(attr, "__marshmallow_hook__", None) instead. The hooks found and their order are the same, and the existing decorator tests cover them.

Class creation is usually a one-time cost, but Schema.from_dict creates a class on every call. webargs does that for each request that uses a dict argmap (@use_args({...})).

CPU time per call, median of 11 alternating rounds in one process, CPython 3.14 on Linux.

Case Before After Speedup
Schema.from_dict(argmap)().load(query), 4 fields 179 us 125 us 1.44x
Create a schema class with 2 fields 120 us 75 us 1.61x

A second run gave 1.50x and 1.71x.

I used Claude Code (Claude Opus 5.5) to profile, write this change and its test, and run the old-vs-new checks and benchmarks above.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant