⚡️ Speed up function _customize_tool_def
by 30%
#24
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
📄 30% (0.30x) speedup for
_customize_tool_def
inpydantic_ai_slim/pydantic_ai/models/__init__.py
⏱️ Runtime :
77.1 microseconds
→59.5 microseconds
(best of329
runs)📝 Explanation and details
REFINEMENT Let's analyze the line profiler stats.
replace()
calls and thetransformer(...).walk()
call.replace()
is called potentially twice per function call, creating new altered copies ofToolDefinition
. Allocating new dataclasses is expensive compared to updating in-place. However, since you require equivalent return values, and since dataclasses are typically frozen (frozen=True
) for immutability (as it seems here), we can't mutate them directly.walk()
method andis_strict_compatible
property are called on the transformer. It would help to avoid constructing multiple dataclasses when we could build everything in a singlereplace
call.t.strict
is notNone
, the firstreplace
is skipped. But if it isNone
, there are two allocations of the dataclass due to tworeplace()
calls.Optimization plan
parameters_json_schema
and newstrict
value before anyreplace
call, and issue only one call toreplace()
.Key:
If
t.strict is None
, we want both newparameters_json_schema
and an updatedstrict
.If
t.strict is not None
, just updateparameters_json_schema
(leavestrict
alone).Here’s the optimized code.
Why is this faster?
replace
calls.If you're allowed to mutate
t
in-place (i.e., ifToolDefinition
is NOT frozen or you control its mutability), it could be even faster, but this would change semantics.This version preserves the semantics, and is the most optimal without change of return values or mutability.
Let me know if mutability is permitted, and I can make this even faster!
✅ Correctness verification report:
🌀 Generated Regression Tests and Runtime
To edit these changes
git checkout codeflash/optimize-_customize_tool_def-mdetgyjy
and push.