【发布时间】:2013-10-21 10:30:22
【问题描述】:
有什么方法可以以某种方式使用 pypy 来编译一个函数而不是用于我的 python 程序的其余部分?
我有一个已知的瓶颈,我花费了 99% 的 CPU 时间(主要包含整数移位和 XOR),并在 Python 中尽可能多地对其进行了优化。除非绝对必要,否则我不想编写和维护 C 库。
现在我正在使用 Anaconda Python,它是带有一堆库的普通 Python。我会使用 pypy,但我不想确保我的程序的所有其余部分都可以使用 pypy。
有没有办法只在一个 Python 函数上显式运行 JIT?
编辑:该函数是 GF2(伽罗瓦域)中的模乘步骤
具体来说:
def _gf2mulmod(x,y,m):
z = 0
while x > 0:
if (x & 1) != 0:
z ^= y
y <<= 1
y2 = y ^ m
if y2 < y:
y = y2
x >>= 1
return z
它需要为 bigints 工作,所以我不确定如何重写以与 Cython 兼容。
我刚刚尝试了 numba 的 @autojit,但它失败了,因为它不知道要使用什么变量类型并且假定为小整数。我似乎不知道如何告诉它使用标准 Python bigints。
Traceback (most recent call last):
File "/Users/jason_s/Documents/python/libgf2/src/libgf2/gf2.py", line 440, in <module>
dlog43 = GF2DiscreteLog(0x100000000065)
File "/Users/jason_s/Documents/python/libgf2/src/libgf2/gf2.py", line 295, in __init__
factors = _calculateFactors(poly)
File "/Users/jason_s/Documents/python/libgf2/src/libgf2/gf2.py", line 264, in _calculateFactors
if (e1 << m).value != 1:
File "/Users/jason_s/Documents/python/libgf2/src/libgf2/gf2.py", line 379, in __lshift__
return self._wrapraw(_gf2lshiftmod(self.value,k,self.poly))
File "/Users/jason_s/Documents/python/libgf2/src/libgf2/gf2.py", line 195, in _gf2lshiftmod
return _gf2mulmod(x,_gf2powmod(2,k,m),m)
File "/Users/jason_s/Documents/python/libgf2/src/libgf2/gf2.py", line 189, in _gf2powmod
z = _gf2mulmod(z,x,m)
File "numbawrapper.pyx", line 193, in numba.numbawrapper._NumbaSpecializingWrapper.__call__ (numba/numbawrapper.c:3764)
OverflowError: value too large to convert to signed int
【问题讨论】:
-
写在Cython中,编译成C扩展。生成的 Cython 代码可能看起来与您当前的代码没有太大不同。
-
试试
numba可能吗? numba.pydata.org -
该功能多长时间?能发一下代码吗?有很多方法可以绕过瓶颈,而最好的方法取决于您具体在做什么。
-
@SvenMarnach:很短;见上文。
-
我尝试了 numba,但无法正常工作。 Anaconda Python 似乎没有 Cython 支持。废话。 :-(