最近在学习Rust
,这是一门系统级语言。保证安全的同时摆脱了GC
, 它很香同时也很难上手, 刚学完一点皮毛知识决定做个小玩意儿玩玩,是骡子是马总要拉出来溜溜~
目前个人认为Rust
在性能上是可以和C++
媲美的一门语言,既然如此那就用它来为Python
加个速吧!😊
起步准备 为Python
加速与写C语言
扩展类似,最终通过pyd
来调用。在此之前我们用到Rust
的pyo3
库,另外我们编写的是一个lib
而不是应用程序,因此我们要创建lib
项目。
创建lib
库项目:
$ cargo new <project name> --lib
在 Cargo.toml 文件添加pyo3
依赖:
1 2 3 4 5 6 7 [lib] name = "string_sum" crate-type = ["cdylib" ][dependencies.pyo3] version = "0.15.1" features = ["extension-module" ]
一个小Demo 使用文档的例子,编写一个Hello World
试试,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 use pyo3::prelude::*;#[pyfunction] fn sum_as_string (a: usize , b: usize ) -> PyResult<String > { Ok ((a + b).to_string ()) } #[pymodule] fn string_sum (py: Python, m: &PyModule) -> PyResult<()> { m.add_function (wrap_pyfunction!(sum_as_string, m)?)?; m.add_function (wrap_pyfunction!(test_func, m)?)?; Ok (()) }
然后用打包命令将这个项目build一下:$ cargo build --release
这时候应该能看到项目的结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 . ├─src └─target ├─release │ ├─.fingerprint │ ├─build │ ├─deps │ ├─examples | ├─string_sum.dll | ├─string_sum.d | ├─libstring_sum.dll.a │ └─incremental └─rls
这里的string_sum.dll 就是我们需要的,我们将文件的扩展名改成pyd
即可得到我们的python
扩展文件 -> string_sum.pyd
完成之后尝试一下调用这个文件,新建一个test
文件夹并将其复制进去, 最后调用一下:
1 2 3 4 import string_sumprint (string_sum.sum_as_string(200 , 33 ))
CPU运算性能Demo 继续在刚刚的文件中添加一个需要大量计算的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ... #[pyfunction] fn test_func () -> PyResult<String > { for a in 0 ..10 { for b in 0 ..10 { for c in 0 ..10 { for d in 0 ..10 { for e in 0 ..10 { for f in 0 ..10 { if m (a) + m (b) + m (c) + m (d) + m (e) + m (f) == a * 10_0000 + b * 1_0000 + c * 1000 + d * 100 + e * 10 + f { println! ("{}{}{}{}{}{}" , a, b, c, d, e, f); } } } } } } } return Ok (String ::new ()); } #[pymodule] fn string_sum (py: Python, m: &PyModule) -> PyResult<()> { m.add_function (wrap_pyfunction!(test_func, m)?)?; Ok (()) }
后续的步骤与上面一致,编译重命名后拷贝到python
目录下,修改一下刚才的python
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 import string_sumimport timedef target_func (): def m (x ): return x * x * x * x * x for a in range (0 ,10 ): for b in range (0 ,10 ): for c in range (0 ,10 ): for d in range (0 ,10 ): for e in range (0 ,10 ): for f in range (0 ,10 ): if m(a) + m(b) + m(c) + m(d) + m(e) + m(f) == a * 10_0000 + b * 1_0000 + c * 1000 + d * 100 + e * 10 + f: print (f"{a} {b} {c} {d} {e} {f} " ) def test_fun (func, flage:str = "Python" ): """计时函数 Args: func (function): 回调函数 """ start = time.time() func() end = time.time() print (f"{flage} time: " ,end - start) return start - end rust_time = test_fun(string_sum.test_func, flage="Rust" ) python_time = test_fun(target_func) print (f"Rate: {python_time/rust_time} " )
运行看一下结果,从结果看到Rust
比Python
足足快了125倍 多!!!