使用Rust加速Python
Posted 朝晖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Rust加速Python相关的知识,希望对你有一定的参考价值。
https://josephok.github.io/2019/03/30/Speed-up-Python-program-with-Rust/
Python
具有开发快速的特点,但是在运行效率上比静态编译型语言慢不少,我们今天要介绍的Rust
就是其中一种。
Rust是一种安全、并发、实用的编程语言,有着惊人的运行速度,能够防止段错误,并保证线程安全,使每个人都能够构建可靠、高效的软件。
当我们的Python
程序出现性能瓶颈时,可以从如下几个方面优化:
- 优化算法,使用更高效率的算法来提升性能;
- 使用并发,如多线程程序;
- 使用编译型语言编写扩展;
- 优化网络、磁盘、数据库等。
性能优化是个大命题,我们需要从多个方面着手考虑,今天我介绍的是第3种方法,并且选择Rust
语言。我们将编写一个so
扩展供Python
端调用。
这里不会讲Rust
的入门,具体规范可以看官方文档或者中文文档:https://rustlang-cn.org/
我们选择Httpbin作为基准程序,进行修改然后对比效果。
1. 原始代码
为了简单,我稍微修改了view_get
,使之只返回客户端的请求方法。如下:
1
|
{
|
代码如下:
1
|
# httpbin/core.py
|
2. 测试一下原始代码性能:
使用wrk进行benchmark测试:
1
|
wrk http://127.0.0.1:5000/get -c 400 -t 10
|
可以看出:平均时延为315ms左右,RPS为434左右。
3. 使用rust-cpython编写扩展
首先新建一个lib
类型的项目,比如名字为handle
:
1
|
cargo new handle --lib
|
这样就在当前项目下新建了一个目录:handle
,我们需要编辑handle/Cargo.toml
:
1
|
[package]
|
然后是编辑handle/src/lib.rs
:
1
|
|
这里的handle
是模块名,ret_py_dict
就是模块的方法,供Python
调用,使用方法:
1
|
import handle
|
然后需要编译此模块,我们使用Makefile
编写编译规则:
1
|
build:
|
执行make
命令编译并将so
文件拷贝到指定目录。
4. Python
端调用方法
编写一个view_get1
方法:
1
|
from . import handle
|
与我们的原始函数唯一区别是:jsonify
函数的参数,即响应内容是由扩展模块产生,类型都是dict
。
curl
响应为:
1
|
curl localhost:5000/get1
|
结果一致。
5. 测试使用了扩展的性能
1
|
wrk http://127.0.0.1:5000/get1 -c 400 -t 10
|
可以看出:平均时延为248ms左右,RPS为544左右。
比原始版本:时延低70ms,RPS高110,效果比较明显,这里仅仅改写了获取对象属性的方式。
6. 总结
如果想继续优化,可以考虑改写jsonify
函数。在这里我们提出了一个优化Python
程序性能(Latency, RPS)的方案。前文也说到过,优化性能应该先从代码结构、算法方面做优化,当语言成为瓶颈时,使用Rust
编写扩展实为一种好的方式。
参考:
https://developers.redhat.com/blog/2017/11/16/speed-python-using-rust/
以上是关于使用Rust加速Python的主要内容,如果未能解决你的问题,请参考以下文章