Skip to content

Conversation

misrasaurabh1
Copy link
Contributor

📄 decimal_places_validator in pydantic/_internal/_validators.py

✨ Performance Summary:

  • Speed Increase: 📈 24% (0.24x faster)
  • Runtime Reduction: ⏱️ From 182 microseconds down to 147 microseconds (best of 159 runs)

📝 Explanation and details

Here are the changes made to the code for optimization.

  1. Calling _extract_decimal_digits_info function isn't required when (decimal_places_ > decimal_places) does not hold true.

Correctness verification

The new optimized code was tested for correctness. The results are listed below:

Test Status Details
⚙️ Existing Unit Tests 🔘 None Found
🌀 Generated Regression Tests 23 Passed See below
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 1 Passed
📊 Coverage 100.00%

🌀 Generated Regression Tests Details

Click to view details
from decimal import Decimal
from typing import Any

# imports
import pytest  # used for our unit tests
from pydantic._internal._validators import decimal_places_validator
from pydantic_core._pydantic_core import PydanticKnownError

# unit tests

# Basic Test Cases
def test_valid_decimal_exact_places():
    codeflash_output = decimal_places_validator(Decimal('1.23'), 2)
    codeflash_output = decimal_places_validator(Decimal('0.123'), 3)

def test_valid_decimal_less_places():
    codeflash_output = decimal_places_validator(Decimal('1.2'), 2)
    codeflash_output = decimal_places_validator(Decimal('0.1'), 3)

def test_invalid_decimal_more_places():
    with pytest.raises(PydanticKnownError):
        decimal_places_validator(Decimal('1.234'), 2)
    with pytest.raises(PydanticKnownError):
        decimal_places_validator(Decimal('0.1234'), 3)

# Edge Test Cases
def test_non_normalized_input():
    codeflash_output = decimal_places_validator(Decimal('1.2300'), 3)
    codeflash_output = decimal_places_validator(Decimal('0.1230'), 3)


def test_zero_value():
    codeflash_output = decimal_places_validator(Decimal('0'), 0)
    codeflash_output = decimal_places_validator(Decimal('0.0'), 1)

def test_negative_values():
    codeflash_output = decimal_places_validator(Decimal('-1.23'), 2)
    codeflash_output = decimal_places_validator(Decimal('-0.123'), 3)

def test_large_numbers():
    codeflash_output = decimal_places_validator(Decimal('123456789.123456789'), 9)
    codeflash_output = decimal_places_validator(Decimal('123456789.1234567890'), 10)

# Invalid Inputs
def test_non_decimal_types():
    with pytest.raises(TypeError):
        decimal_places_validator('1.23', 2)
    with pytest.raises(TypeError):
        decimal_places_validator(1.23, 2)
    with pytest.raises(TypeError):
        decimal_places_validator(None, 2)

# Boundary Conditions
def test_maximum_decimal_places():
    codeflash_output = decimal_places_validator(Decimal('1.' + '0'*28 + '1'), 29)
    with pytest.raises(PydanticKnownError):
        decimal_places_validator(Decimal('1.' + '0'*28 + '1'), 28)

def test_minimum_decimal_places():
    codeflash_output = decimal_places_validator(Decimal('1.0'), 0)
    with pytest.raises(PydanticKnownError):
        decimal_places_validator(Decimal('1.1'), 0)

# Large Scale Test Cases
def test_large_scale():
    codeflash_output = decimal_places_validator(Decimal('1.' + '0'*1000 + '1'), 1001)
    with pytest.raises(PydanticKnownError):
        decimal_places_validator(Decimal('1.' + '0'*1000 + '1'), 1000)
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

📣 **Feedback**

If you have any feedback or need assistance, feel free to join our Discord community:

Discord

codeflash-ai bot and others added 2 commits December 3, 2024 23:41
Here are the changes made to the code for optimization.

1. Avoided repeated calls to expensive functions like `len()`.
2. Simplified some logic to minimize computations.
3. Removed the redundant instances of re-extracting decimal info where possible.




Points of optimization.
- Avoided `assert` statement which is typically disabled in optimized mode.
- Simplified the conditional blocks and reduced the number of function calls and length calculations.
@github-actions github-actions bot added the relnotes-fix Used for bugfixes. label Jan 16, 2025
Copy link

codspeed-hq bot commented Jan 16, 2025

CodSpeed Performance Report

Merging #11281 will not alter performance

Comparing misrasaurabh1:codeflash/optimize-decimal_places_validator-2024-12-03T23.41.41 (197ab22) with main (dac74dc)

Summary

✅ 45 untouched benchmarks

Copy link
Contributor

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  pydantic/_internal
  _validators.py
Project Total  

This report was generated by python-coverage-comment-action

@Viicos Viicos changed the title ⚡️ Speed up function decimal_places_validator by 24% [codeflash] Only compute normalized decimal places if necessary in decimal_places_validator Jan 16, 2025
@Viicos Viicos enabled auto-merge (squash) January 16, 2025 11:07
@Viicos Viicos merged commit 46f3075 into pydantic:main Jan 16, 2025
53 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
relnotes-fix Used for bugfixes.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants