gpt4 book ai didi

python - 为什么 cython embed 插件在 python 解释器中的性能比 rust-c 接口(interface)版本更高?

转载 作者:行者123 更新时间:2023-12-03 11:46:29 40 4
gpt4 key购买 nike

想请教一些关于python解释器底层原理的问题,因为自己搜索的过程中没有得到太多有用的信息。

我最近一直在用rust写python插件,这对python的cpu密集型任务有显着的加速,而且写起来比c更快。不过它有一个缺点就是,相对于老的用cython加速的方案,rust(我用的是pyo3)的调用开销好像比c(我用的是cython)要大,

例如,我们在这里得到一个空的 python 函数:

def empty_function():
return 0

在 Python 中通过 for 循环调用它一百万次并计算时间,这样我们就可以发现每次调用大约需要 70 纳秒(在我的电脑中)。

如果我们将它编译成一个 cython 插件,使用相同的源代码:

# test.pyx
cpdef unsigned int empty_function():
return 0

执行时间将减少到 40 纳秒。这意味着我们可以使用 cython 进行一些细粒度的嵌入,我们可以期望它总是比原生 python 执行得更快。

然而,当涉及到 Rust 时,(老实说,我更喜欢使用 rust 进行插件开发而不是 cython 现在因为不需要在语法上做一些奇怪的黑客攻击),调用时间将增加到 140 纳秒,几乎是两倍与 native python 一样多。源码如下:

use pyo3::prelude::*;
use pyo3::wrap_pyfunction;

#[pyfunction]
fn empty_function() -> usize {
0
}

#[pymodule]
fn testlib(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(empty_function, m)?)?;
Ok(())
}

这意味着rust不适合细粒度的嵌入替代python。如果有一个任务调用时间很少,每次调用时间都比较长,那么用rust就完美了。但是如果有一个任务会在代码中被调用很多,那么它似乎不适合 rust ,因为类型转换的开销会占用大部分加速时间。

我想知道这是否可以解决,更重要的是,我想知道这种差异的根本原因。 cpython 解释器在它们之间调用时是否存在某种差异,例如调用 c 插件时 cpython 和 pypy 之间的差异?我在哪里可以获得更多信息?谢谢。

===

更新:

不好意思各位,没想到我的问题会模棱两可,毕竟三者的源码都给了,使用timeit测试函数运行时几乎是python开发的惯例。

我的测试代码与注释中@Jmb 的代码几乎完全相同,有一些细微的差别,我使用 python setup.py build_ext --inplace 方式来构建而不是裸gcc,但这应该没有任何区别。总之谢谢补充。

最佳答案

这里还值得注意的是,使用 python setup.py build_ext --inplace 编译 Rust 扩展会在未优化模式下构建它们(同样适用于 python setup.py developpip install -e .).

以下是输出的摘录:

Finished dev [unoptimized + debuginfo] target(s) in 0.02s

要使用优化的二进制文件以“发布”模式构建,请使用:

pip install .

使用 pip 安装。 --verbose 你可以看到区别:

Finished release [optimized] target(s) in 1.02s

这会产生巨大的差异,在我的例子中,未优化的构建比优化的构建慢 9 倍。

关于python - 为什么 cython embed 插件在 python 解释器中的性能比 rust-c 接口(interface)版本更高?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66467640/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com