Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Optimize creation of unnormalized Fraction's in private methods (arithmetics, etc) #101773

Closed
Labels
performancePerformance or resource usagestdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement
@skirpichev

Description

@skirpichev

Right now we just use__new__() with a private kwarg_normalize=False. That's slightly less efficient, then a dedicated class method.

POC patch

diff --git a/Lib/fractions.py b/Lib/fractions.pyindex 49a3f2841a..27c75785fb 100644--- a/Lib/fractions.py+++ b/Lib/fractions.py@@ -315,6 +315,13 @@ def from_decimal(cls, dec):                 (cls.__name__, dec, type(dec).__name__))         return cls(*dec.as_integer_ratio())+    @classmethod+    def _from_pair(cls, num, den):+        obj = super(Fraction, cls).__new__(cls)+        obj._numerator = num+        obj._denominator = den+        return obj+     def is_integer(self):         """Return True if the Fraction is an integer."""         return self._denominator == 1@@ -703,13 +710,13 @@ def _add(a, b):         nb, db = b._numerator, b._denominator         g = math.gcd(da, db)         if g == 1:-            return Fraction(na * db + da * nb, da * db, _normalize=False)+            return Fraction._from_pair(na * db + da * nb, da * db)         s = da // g         t = na * (db // g) + nb * s         g2 = math.gcd(t, g)         if g2 == 1:-            return Fraction(t, s * db, _normalize=False)-        return Fraction(t // g2, s * (db // g2), _normalize=False)+            return Fraction._from_pair(t, s * db)+        return Fraction._from_pair(t // g2, s * (db // g2))      __add__, __radd__ = _operator_fallbacks(_add, operator.add)

We can drop private kwarg of__new__() after adopting this way.

Some benchmarks

With above patch

$ ./python -m timeit -s 'from fractions import Fraction as Q' -s 'a,b=Q(3,7),Q(5, 8)' -u usec 'a+b'50000 loops, best of 5: 4.4 usec per loop$ ./python -m timeit -s 'from fractions import Fraction as Q' -s 'a,b=Q(3,7)**100,Q(5, 8)**100' -u usec 'a+b'20000 loops, best of 5: 12.6 usec per loop

On themastermain:

$ ./python -m timeit -s 'from fractions import Fraction as Q' -s 'a,b=Q(3,7),Q(5, 8)' -u usec 'a+b'50000 loops, best of 5: 6.99 usec per loop$ ./python -m timeit -s 'from fractions import Fraction as Q' -s 'a,b=Q(3,7)**100,Q(5, 8)**100' -u usec 'a+b'20000 loops, best of 5: 15.9 usec per loop

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    performancePerformance or resource usagestdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp