⚡️ 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_definpydantic_ai_slim/pydantic_ai/models/__init__.py⏱️ Runtime :
77.1 microseconds→59.5 microseconds(best of329runs)📝 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_compatibleproperty are called on the transformer. It would help to avoid constructing multiple dataclasses when we could build everything in a singlereplacecall.t.strictis notNone, the firstreplaceis skipped. But if it isNone, there are two allocations of the dataclass due to tworeplace()calls.Optimization plan
parameters_json_schemaand newstrictvalue before anyreplacecall, and issue only one call toreplace().Key:
If
t.strict is None, we want both newparameters_json_schemaand an updatedstrict.If
t.strict is not None, just updateparameters_json_schema(leavestrictalone).Here’s the optimized code.
Why is this faster?
replacecalls.If you're allowed to mutate
tin-place (i.e., ifToolDefinitionis 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-mdetgyjyand push.