Rust(1) - 如何使用 Rust 使 Python 函数速度提高 5000%

搬运一篇medium的看上去很x的文章:# This Is How You Make Your Python Functions 5000% Faster With Rust (Yes, You Read It Right!)

Rust 被大多数科技巨头广泛采用,甚至白宫现在也建议开发人员使用它来构建关键软件。Rust 对于来自 Python 等动态类型语言的开发人员来说可能具有挑战性。

寻找第 N 个素数:Python 实现

首先用 Python 编写一个函数来查找第 n 个素数(质数)

python 复制代码
def is_prime(num):
    # 检查一个数是否是素数
    if num < 2:
        return False
    for i in range(2, num):
        if num % i == 0:
            return False
    return True

def find_nth_prime(n):
    # 找到第n个素数
    count = 0
    num = 1
    while count < n:
        num += 1
        if is_prime(num):
            count += 1
    return num

让我们使用这个函数计算第 50 个素数

python 复制代码
#prime_finder.py

from timeit import timeit
import sys

# 上面的素数查找函数定义放在这里
# ...

def main():
    n = int(sys.argv[1]) #使用 CLI 接受数字

    print(f"Using Python => The {n} prime number is: {find_nth_prime(n)}")

    ITERATIONS = 100

    python_time_per_iter = timeit(
        lambda: find_nth_prime(n), number=ITERATIONS) / ITERATIONS

    print(
        f"Time taken using Python Prime finder: {python_time_per_iter* 1000:.2f} milliseconds per iteration.")

if __name__ == "__main__":
    main()

当我在终端中执行命令 python prime_finder.py 50 时,获得的响应如下所示

我们的 Python 函数实现花了 0.64 毫秒来找到第 50 个素数

寻找第 N 个素数:Rust 实现

让我们用 Rust 重写相同的函数

rust 复制代码
fn is_prime_rust(num: u32) -> bool {
    if num < 2 {
        return false;
    }

    for i in 2..num {
        if num % i == 0 {
            return false;
        }
    }
    
    true
}

fn find_nth_prime_rust(n: u32) -> u32 {
    let mut count: u32 = 0;
    let mut num: u32 = 1;

    while count < n {
        num += 1;

        if is_prime_rust(num) {
            count += 1;
        }
    }

    num
}

在 Python 中集成 Rust 代码

第 1 步:初始化我们的项目

shell 复制代码
$ mkdir rust_prime_funcs && cd rust_prime_funcs # 创建项目目录

$ python -m venv env # 创建Python虚拟环境

$ source ./env/Scripts/activate # 激活虚拟环境

Step 2: 安装Maturin

接下来,我们使用 Maturin,这是一个工具,可以帮助我们构建和发布带有 pyo3rust-cpythonCFFI 绑定的 crate,以及 Rust 二进制文件作为 Python 包

shell 复制代码
$ pip install maturin  # 使用 pip 安装 maturi

$ maturin init # 初始化 maturin 并在出现提示时选择"pyo3"

Step 3: 使用 Rust 创建 Python 模块

rust 复制代码
// rust_prime_funcs/src/lib.rs

use pyo3::prelude::*;

// Rust 中的辅助函数
#[pyfunction]
fn is_prime_rust(num: u32) -> bool {
    if num < 2 {
        return false;
    }

    for i in 2..num {
        if num % i == 0 {
            return false;
        }
    }

    true
}

// Rust 中的第 N 个素数查找函数
#[pyfunction]
fn find_nth_prime_rust(n: u32) -> u32 {
    let mut count: u32 = 0;
    let mut num: u32 = 1;

    while count < n {
        num += 1;

        if is_prime_rust(num) {
            count += 1;
        }
    }

    num
}

/// 用 Rust 实现的 Python 模块
#[pymodule]
fn rust_prime_funcs(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(find_nth_prime_rust, m)?)?;
    Ok(())
}

Step 4: 构建 Python 模块

使用以下命令通过终端构建 Python 模块

shell 复制代码
$ maturin develop --release

Step 5: 比较 Python 与 Rust 函数性能

python 复制代码
# rust_prime_funcs/test/prime_finder.py

import sys
from timeit import timeit

from rust_prime_funcs import find_nth_prime_rust

def is_prime(num):
    # 检查一个数是否是素数
    if num < 2:
        return False
    for i in range(2, num):
        if num % i == 0:
            return False
    return True

def find_nth_prime(n):
    # 找到第n个质数
    count = 0
    num = 1
    while count < n:
        num += 1
        if is_prime(num):
            count += 1
    return num

def main():
    n = int(sys.argv[1])

    print(f"\nUsing Python => The {n} prime number is: {find_nth_prime(n)}")
    print(f"Using Rust => The {n} prime number is: {find_nth_prime_rust(n)}")

    ITERATIONS = 100

    python_time_per_iter = timeit(
        lambda: find_nth_prime(n), number=ITERATIONS) / ITERATIONS

    rust_time_per_iter = timeit(
        lambda: find_nth_prime_rust(n), number=ITERATIONS) / ITERATIONS

    print(
        f"\nTime taken using Python Prime finder: {python_time_per_iter* 1000:.2f} milliseconds per iteration.")

    print(
        f"Time taken using Rust Prime finder: {rust_time_per_iter * 1000:.2f} milliseconds per iteration.")

    if python_time_per_iter > rust_time_per_iter:
        performance = (
            (python_time_per_iter - rust_time_per_iter) / rust_time_per_iter) * 100
        print(f"\nRust code is faster than Python by {performance:.2f}%\n")
    else:
        performance = (
            (rust_time_per_iter - python_time_per_iter) / python_time_per_iter) * 100
        print(f"\nPython code is faster than Rust by {performance:.2f}%\n")

if __name__ == "__main__":
    main()

执行后比较性能

用于查找第 n 个素数的 Rust 函数比我们的 Python 实现快了 5264.74%,即几乎 53 倍。

上面这个例子是在 Python 代码中使用 Rust 的简单示例,但有一些重要的库要么提供 Python 到 Rust 代码的绑定,要么完全用 Rust 编写

比如:

  • orjson: 一个快速、正确的 Python JSON 库
  • pydantic: 一个流行的数据验证库
  • Polars: 用于高效数据操作和分析的快速 DataFrame 库
  • tokenizers : 由 Hugging Face 构建的快速高效的文本标记化和预处理
  • cryptography: 用于实现密码操作的库
  • PyOxidizer: 现代Python应用程序打包和分发工具
  • retworkx: 专为量子计算和其他科学应用而开发的高性能图形库
相关推荐
姜学迁17 小时前
Rust-枚举
开发语言·后端·rust
凌云行者17 小时前
rust的迭代器方法——collect
开发语言·rust
QMCY_jason1 天前
Ubuntu 安装RUST
linux·ubuntu·rust
碳苯1 天前
【rCore OS 开源操作系统】Rust 枚举与模式匹配
开发语言·人工智能·后端·rust·操作系统·os
zaim11 天前
计算机的错误计算(一百一十四)
java·c++·python·rust·go·c·多项式
凌云行者2 天前
使用rust写一个Web服务器——单线程版本
服务器·前端·rust
cyz1410012 天前
vue3+vite@4+ts+elementplus创建项目详解
开发语言·后端·rust
超人不怕冷2 天前
[rust]多线程通信之通道
rust
逢生博客2 天前
Rust 语言开发 ESP32C3 并在 Wokwi 电子模拟器上运行(esp-hal 非标准库、LCD1602、I2C)
开发语言·后端·嵌入式硬件·rust
Maer092 天前
WSL (Linux)配置 Rust 开发调试环境
linux·运维·rust