Author scoder
Recipients scoder
Date 2014-09-22.17:37:13
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1411407434.75.0.285038516488.issue22464@psf.upfronthosting.co.za>
In-reply-to
Content
Fractions are an excellent way to do exact money calculations and largely beat Decimal in terms of simplicity, accuracy and safety. Clearly not in terms of speed, though.

The current implementation does some heavy type checking and dispatching in __new__() and a simplistic gcd based normalisation. Here is a profiling run from the benchmark proposed in issue 22458 (which matches more or less the results with my own code):

         6969671 function calls (6969278 primitive calls) in 4.835 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   519644    1.324    0.000    2.928    0.000 fractions.py:73(__new__)
   519632    0.654    0.000    0.654    0.000 fractions.py:17(gcd)
   319744    0.637    0.000    2.694    0.000 fractions.py:400(_add)
  1039260    0.507    0.000    0.950    0.000 abc.py:178(__instancecheck__)
        4    0.459    0.115    4.821    1.205 bm_telco_fractions.py:38(run)
  1039300    0.443    0.000    0.443    0.000 _weakrefset.py:70(__contains__)
   519616    0.301    0.000    4.329    0.000 fractions.py:373(forward)
   199872    0.272    0.000    1.335    0.000 fractions.py:416(_mul)
  1598720    0.117    0.000    0.117    0.000 fractions.py:278(denominator)
   959232    0.074    0.000    0.074    0.000 fractions.py:274(numerator)

The instantiation itself takes twice as much time as the gcd calculations, and both dominate the overall runtime of the benchmark by about 60%. Improving the instantiation time would thus bring a substantial benefit.
History
Date User Action Args
2014-09-22 17:37:14scodersetrecipients: + scoder
2014-09-22 17:37:14scodersetmessageid: <1411407434.75.0.285038516488.issue22464@psf.upfronthosting.co.za>
2014-09-22 17:37:14scoderlinkissue22464 messages
2014-09-22 17:37:13scodercreate