【发布时间】:2023-03-21 02:10:01
【问题描述】:
我有一个函数,它基本上只是对一个简单定义的哈希函数进行大量调用,并测试它何时找到重复项。我需要用它做很多模拟,所以希望它尽可能快。我正在尝试使用 cython 来做到这一点。 cython 代码当前使用正常的 Python 整数列表调用,其值范围为 0 到 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
如何转换 inputx 和 listofpos 以使用 C 类型数组并以 C 速度访问数组?我可以使用其他加速吗? setofvalues 可以加速吗?
所以有一些东西可以比较,50 次 m = 5000 的 floyd() 调用目前在我的计算机上大约需要 30 秒。
更新:示例代码 sn-p 显示如何调用 floyd。
m = 5000
inputx = random.sample(xrange(m**2), m)
(dupefound, nohashcalls) = edcython.floyd(inputx)
【问题讨论】:
-
你有没有想过添加一种机制来记忆过去的结果?我看到了对
hash方法的重叠调用的可能性,这可以在牺牲内存空间的情况下大大加快您的算法。 -
你的意思是存储h3的结果吗?该功能一旦找到重复项就会停止,因此这似乎没有帮助。我怀疑主要的加速将来自使用 C 类型的数组,但我不知道该怎么做。
-
floyd的确切输入是什么?我假设只是一个list的整数? -
这里是一个例子。米= 5000 。 inputx = random.sample(xrange(m**2), m) 。 (dupefound, nohashcalls) = edcython.floyd(inputx) .
标签: python optimization cython