我有一个函数,它基本上对很多简单定义的哈希函数进行调用,并测试它是否发现重复。我需要用它做很多模拟,所以希望它尽可能快。我正在尝试使用cython来做到这一点。 cython代码当前使用一个普通的python整数列表调用,其值在0到m^2之间。使用cython加速python代码
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
如何将inputx和listofpos转换为使用C类型数组并以C速度访问数组?有没有其他的速度可以使用? setofvalues可以加快吗?
因此,有一点可以与之比较,在m = 5000时调用floyd()的50个调用当前大约需要30秒。
更新:示例代码片段,以显示如何调用floyd。
m = 5000
inputx = random.sample(xrange(m**2), m)
(dupefound, nohashcalls) = edcython.floyd(inputx)
你有没有想过在一个机制来记住过去的结果加入?我发现重复调用'hash'方法的可能性,这会在牺牲内存空间的同时显着加速算法。 – sean
你的意思是存储h3的结果吗?该函数一旦发现重复就停止,所以这似乎没有帮助。我怀疑主要的加速会来自使用C型阵列,但我不知道如何做到这一点。 – Raphael
“floyd”的确切输入是什么?我假设只是一个整数列表? – sean