Przyspieszenie kodu Pythona za pomocą cythona
Mam funkcję, która w zasadzie wykonuje wiele wywołań prostej zdefiniowanej funkcji skrótu i testów, aby sprawdzić, kiedy znajdzie duplikat. Muszę zrobić z nim wiele symulacji, aby był jak najszybszy. Próbuję użyć do tego cython. Kod cythona jest obecnie wywoływany z normalną listą pytonów liczb całkowitych o wartościach z zakresu od 0 do m ^ 2.
import math, random
cdef int a,b,c,d,m,pos,value, cyclelimit, nohashcalls
def h3(int a,int b,int c,int d, int m,int x):
return (a*x**2 + b*x+c) %m
def floyd(inputx):
dupefound, nohashcalls = (0,0)
m = len(inputx)
loops = int(m*math.log(m))
for loopno in xrange(loops):
if (dupefound == 1):
break
a = random.randrange(m)
b = random.randrange(m)
c = random.randrange(m)
d = random.randrange(m)
pos = random.randrange(m)
value = inputx[pos]
listofpos = [0] * m
listofpos[pos] = 1
setofvalues = set([value])
cyclelimit = int(math.sqrt(m))
for j in xrange(cyclelimit):
pos = h3(a,b, c,d, m, inputx[pos])
nohashcalls += 1
if (inputx[pos] in setofvalues):
if (listofpos[pos]==1):
dupefound = 0
else:
dupefound = 1
print "Duplicate found at position", pos, " and value", inputx[pos]
break
listofpos[pos] = 1
setofvalues.add(inputx[pos])
return dupefound, nohashcalls
Jak mogę przekonwertować inputx i listofpos, aby użyć tablic typu C i uzyskać dostęp do tablic przy prędkości C? Czy są jakieś inne przyspieszenia, których mogę użyć? Czy można zwiększyć wartości setofvalue?
Aby można było porównywać, 50 połączeń do floyd () z m = 5000 trwa obecnie około 30 sekund na moim komputerze.
Aktualizacja: przykładowy fragment kodu pokazujący, jak nazywa się floyd.
m = 5000
inputx = random.sample(xrange(m**2), m)
(dupefound, nohashcalls) = edcython.floyd(inputx)