9

这是我的基本问题:

我有一个导入的 Python 文件

from math import sin,cos,sqrt

我需要这个文件仍然 100% 兼容 CPython,以允许我的开发人员编写 100% CPython 代码并使用为 Python 开发的出色工具。

现在输入 Cython。在我的 Python 文件中,三角函数被调用了数百万次(代码的基础,无法更改)。有什么方法可以通过主 python 文件中的一些 Python-fu 或 Cython 魔法,否则我可以使用 C/C++ 数学函数,使用 Cython 代码的一些变体

cdef extern from "math.h":
    double sin(double)

这会给我带来接近 C 的性能,这太棒了。

Stefan 的演讲特别说这不能做,但是演讲已经有两年了,而且有很多有创造力的人

4

4 回答 4

3

在 Cython 文档的示例中,他们使用 C 库中的 cimport 来实现此目的:

from libc.math cimport sin
于 2013-04-26T16:21:01.837 回答
2

我不是 Cython 专家,但 AFAIK,你所能做的就是写一个 Cython 包装器sin并调用它。不过,我无法想象这真的会比 快math.sin,因为它仍然使用 Python 调用语义——开销在于调用函数的所有 Python 内容,而不是实际的三角计算,使用时在 C 中完成CPython 也是。

您是否考虑过使用Cython 纯模式,这使得源 CPython 兼容?

于 2012-04-27T12:57:32.147 回答
1

八年后回答这个问题,这就是我在 Ubuntu 19.10 上使用来自 Ubuntu 存储库的系统 CPython vesion 3.7.5 和 Cython3 版本 0.29.10 的方法。

有关纯 Python 模式的 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 的数学模块。

cython3 --embed mymodule.py

gcc -o mymodule mymodule.c -I/usr/include/python3.7 -lpython3.7m -lm
于 2020-04-12T19:51:55.807 回答
0

我可能误解了您的问题,但Cython 与外部 C 代码接口的文档似乎建议使用以下语法:

cdef extern from "math.h":
    double c_sin "sin" (double)

它为函数提供sin了 C 代码中的名称(以便它正确链接到来自 的函数math.h)和c_sinPython 模块中的名称。不过,我不确定我是否理解在这种情况下实现了什么 - 为什么要math.sin在 Cython 代码中使用?你有一些静态类型的变量和一些动态类型的变量吗?

于 2012-04-27T13:16:54.883 回答