这是我的基本问题:
我有一个导入
的Python文件from math import sin,cos,sqrt
我需要这个文件仍然是100%CPython兼容,以允许我的开发人员编写100%的CPython代码并使用为Python开发的优秀工具。
现在进入Cython。在我的Python文件中,trig函数被调用数百万次(代码的基础,不能改变它)。有没有办法通过主python文件中的一些Python-fu,或Cython魔术,否则我可以使用C / C ++数学函数使用Cython代码上的一些变体
cdef extern from "math.h":
double sin(double)
这会给我近乎C的表现,这将是非常棒的。
Stefan's talk具体说不能这样做,但谈话已经两年了,那里有很多有创意的人
答案 0 :(得分:2)
我不是Cython专家,但是AFAIK,你所能做的就是在sin
周围写一个Cython包装并调用它。我无法想象这会比math.sin
更快,因为它仍然使用Python调用语义 - 所有Python内容的开销都是调用函数,而不是实际的trig计算,在使用CPython时也在C中完成。
您是否考虑使用Cython pure mode,这使源CPython兼容?
答案 1 :(得分:2)
在Cython文档的example中,他们使用C库中的cimport来实现这一点:
from libc.math cimport sin
答案 2 :(得分:1)
八年后回答了这个问题,这对我来说是有效的,它使用来自Ubuntu repostory的系统CPython vesion 3.7.5和Cython3版本0.29.10在Ubuntu 19.10上工作。
Pure Python Mode上的Cython文档给出了一个有效的示例。它看起来与此处的旧答案中的示例有所不同,因此我认为此文档自此以来已进行了更新。
Python文件需要有条件导入,使用常规CPython可以正常工作:
#!/usr/bin/env python3
# from: https://cython.readthedocs.io/en/latest/src/tutorial/pure.html
# mymodule.py
import cython
# override with Python import if not in compiled code
if not cython.compiled:
from math import sin
# calls sin() from math.h when compiled with Cython and math.sin() in Python
print(sin(0.5))
Cython语言构造必须放在具有相同名称但后缀为“ .pxd”的文件中:
#cython: language_level=3
# from: https://cython.readthedocs.io/en/latest/src/tutorial/pure.html
# mymodule.pxd
# declare a C function as "cpdef" to export it to the module
cdef extern from "math.h":
cpdef double sin(double x)
我使用“ --embed”选项为独立的Linux ELF可执行文件创建了C代码,以对此进行测试。 GCC编译器行需要使用“ -lm”来导入包含sin的maths模块。
cython3 --embed mymodule.py
gcc -o mymodule mymodule.c -I/usr/include/python3.7 -lpython3.7m -lm
答案 3 :(得分:0)
我可能误解了您的问题,但Cython documentation on interfacing with external C code似乎建议使用以下语法:
cdef extern from "math.h":
double c_sin "sin" (double)
在C代码中赋予函数名称sin
(以便它正确链接到math.h
中的函数),并在Python模块中赋予c_sin
。我不确定我是否理解在这种情况下实现了什么,但是为什么你想在Cython代码中使用math.sin
?你有一些静态类型的变量,还有一些动态类型的变量?