[python] как быстро сделать decimal*100 -> int

Phoenix

 

import sys
from time import sleep
from datetime import datetime,timedelta

from decimal import Decimal

DPREC = 1
PREC = 10**DPREC

def main:
begin = datetime.now
a = Decimal('1.45434')
for i in range(1000000):
b = int (a* PREC )



end = datetime.now
print 'delta: %s' % (end-begin)

begin = datetime.now
a = Decimal('1.45434')
for i in range(1000000):
b = int (float(a)* PREC )



end = datetime.now
print 'delta: %s' % (end-begin)

def check:
for a in xrange(PREC):
buf = '%d.%0*d' % (10**(16-DPREC DPREC, a)
d = Decimal(buf)
print d
res1 = int (d*PREC)
res2 = int (float(d) * PREC)

print res1, res2
assert res1 == res2, 'FcUK!'

main:
delta: 0:00:23.672000
delta: 0:00:04.750000
Прилично. Учитывая, что операция будет выполняться где-то 1000 раз в секунду, получается, что первый способ занимает 1/43 всего времени. А ему как-то нужно другим, более важным заниматься.
вторая фукнция показывает, что при любом DPREC, получает неточность из-за округления.
F:\igor\apps\devel\python\speedtest>python stest.py
1000000000000000.0
10000000000000000 10000000000000000
1000000000000001.1
10000000000000011 10000000000000012
Traceback (most recent call last):
File "stest.py", line 46, in <module>
check
File "stest.py", line 40, in check
assert res1 == res2, 'FUCK! %d' % (res1 - res2)
AssertionError: FUK! -1

Данные получаю через стороннюю библиотеку, они присылает их в Decimal, так что от него не уйти.
Вопрос такой, как можно соптимизировать?

Phoenix

т.е. хочется что-то типа такого, но не корявого.
    begin = datetime.now
a = Decimal('1.45434')
for i in range(1000000):
ip,fp = str(a).split('.')
#if len(fp)< DPREC
b = int(ip)* PREC + int(fp)



end = datetime.now
print 'delta: %s' % (end-begin)

delta: 0:00:05.219000

Phoenix

блин. не заметил. надеюсь, чтение приватной переменной не сильно плохо?
 
   
begin = datetime.now
a = Decimal('1.45434')
for i in range(1000000):
b = a._int



end = datetime.now

delta: 0:00:00.172000
ускорение в 100раз. :grin:
Правда непонятно, в чём тормознутость int (d* 100)
умножение - умножение d._int
округление d._int / 10** (-d._exp)
ну всяко должно быть быстрее, чем разбор строки.
Оставить комментарий
Имя или ник:
Комментарий: