如果你想加速一些现有的 Python 代码,用 Rust 编写编译扩展可能是一个很好的选择:
- 在许多情况下,Rust 代码的运行速度比 Python 快得多。
- Rust 可以防止 C、C++ 和 Cython 代码中经常出现的大多数内存管理错误。
- 可用的第三方 Rust 包生态系统正在不断增长,与 C 和 C++ 不同,它还有内置的包管理器和构建系统。
rustimport是一个库,它可以轻松地在 Python 中导入导入独立的 Rust 文件(目前仅在 Linux 和 macOS 上)。
先决条件
rustimport动态编译 Rust 代码,因此您需要在计算机上安装 Rust 编译器。这不是您最终打包的库或应用程序想要的,但我们的用例是原型设计,无论如何您都需要编译器。
您还需要进行rustimport安装,例如pip install rustimport在 virtualenv 或 Conda 环境中运行。
Rust 中实现斐波那契数列:
// rustimport:pyo3 |
use pyo3::prelude::*; |
rustimport可以让你导入 Rust 文件;你所要做的就是import rustimport.import_hook:
In [2] import rustimport.import_hook |
我们刚刚导入了一个 Rust 文件,它会自动编译,然后我们运行代码!
如果我们查看目录中的文件,我们可以看到创建了一个新的已编译的 Python 扩展:
$ ls |
此时我们不需要导入rustimport.import_hook:我们可以只导入扩展,因为它已经编译了:
$ python -c "import rustfib; print(rustfib.fibonacci(10))" |
工作方式
rustimport以多种不同的方式减少您的努力。
首先,rustimport.import_hook将挂接到Python的导入系统;当它看到具有相关名称的 Rust 文件时,它会将其编译为 Python 扩展,然后导入它。为了防止您随机导入现有的任何 Rust 文件,您需要在文件顶部添加特殊注释:
// rustimport:pyo3
其次,用 Rust 编写 Python 扩展的典型方式是使用名为PyO3的第三方库。在正常的 Rust 设置中,您必须添加pyo3依赖项;
而上面代码中 // rustimport: pyo3告诉你rustimport自动为你做这件事。
第三,一个普通的PyO3扩展需要你有一个模块初始化函数,在这里你需要注册函数。在我们的例子中可能是这样的
// This is optional if you're using rustimport: |
rustimport 会自动为您生成这些代码。如果#[pyfunction]和#[pyclass]的默认支持不够,您可以自己编写。
第四,你不需要编写或生成Cargo.toml文件,大多数Rust包都需要。