【发布时间】:2019-07-14 20:34:05
【问题描述】:
我正在努力学习 Cython(请参阅 How to Cythonize a Python Class with an attribute that is a function?)
我有以下想要加速的功能,但 Cython 说两条线都通过 python:
cdef selectindex(float fitnesspref):
r = np.random.rand()
return int(log(r) / log(fitnesspref))
所以我需要得到一个随机数(我最初只是使用 Python 调用中的 random(),但切换到 Numpy 希望它更快或者 Cythonize 更好。然后我需要记录两个浮点数,将它们分开,然后将结果作为整数返回。没什么太难的,应该是一个很好的问题,人们可以稍后使用。我正在努力通过Cython docs 找到我需要的所有信息的简单解决方案或谷歌。我本以为每个教程都是这样,但我运气不好。
但环顾四周,我找不到一个很好的简单解决方案。例如:Canonical way to generate random numbers in Cython
有没有最好但更简单的方法来 Cythonize 这样的函数?
顺便说一句,abs() 也有类似的问题,但在我将所有内容更改为 cdefs 后,它似乎自动切换到使用 C 版本。
我经常碰到的另一个常见问题是:
start = time.time()
即有没有一种简单的方法可以使用 C 代码来加快开始和结束时间?我在内部循环中有那条线,所以它减慢了速度。但这对我想做的事情真的很重要。
更新 1: 我正在尝试遵循 cmets 中的建议,但它们似乎并没有像我预期的那样发挥作用(这就是为什么这一切首先让我感到困惑。)例如,这是我的随机的 c 版本编写并编译。为什么还是黄色?
更新 2: 好的,我进一步研究了它,这就是为什么它不会一直编译到 C:
它正在检查以确保我没有被零除,即使它是一个常数并且永远不可能为零。你如何摆脱它?
【问题讨论】:
-
谢谢,Sachin,我不知道你能做到。从现在开始我会使用它。
-
在大多数情况下,您只想在 C 标准库中找到等效的函数并使用它。您链接到的关于随机数的问题稍微复杂一些,因为他们希望在多个线程中安全地生成数字,但如果您不关心这个问题,那么也有一个简单的 C 标准库函数
-
附带说明,您可能还应该在
selectindex上设置返回类型(即改用cdef int selectindex(float fitnesspref):。 -
一旦你发现 C 函数生成随机数,别忘了给 r 添加一个类型!
-
@BruceNielson 关于零除:1)这可能不是问题——C 编译器会看到它是一个常量并跳过永远不会发生的分支——所以不要太担心黄色; 2)
cdivisioncompiler argument 将关闭它。与以往一样,您应该尽可能在本地应用编译器参数(即函数装饰器或with语句),但值得仔细查看它们以查看可以禁用的内容
标签: python python-3.x cython