2021-08-30

RUST 初学者入门

Why we choose rust?

计算机语言发展这么多年来,语言也层出不穷,经典永不过时的C、C++,以易上手,语法简单的Python,新起之秀Go、Rust。Stack Overflow 的报告显示Rust 连续四年成为最受开发者喜爱的编程语言,不少开发者(如我)萌生了学习Rust的想法,然而我们究竟为何要学习这门语言呢?毕竟学习一门新语言的代价比较高。浏览了众多知乎,blog,stackflow等回答,优点可以总结如下:

  • 安全。Rust 是静态的,拥有丰富类型系统和所有权模型,保证了内存安全性和线程安全性。 C 语言很容易出现整数溢出,如果被黑客利用,很容易出现安全问题。而 Rust 中的每个值都只能被一个所有者拥有,所以 C 语言遇到的这类问题,对 Rust 来说都不是问题;
  • 并发。并发和并行是 IT 圈内不会过时的话题,Rust 可让程序在编译时并发执行,并且将安全与并发完美统一。
  • 高效。没有 Runtime,也没有 GC,所以 Rust 非常快且节省内存,它可以为性能关键型服务提供动力,在嵌入式设备上运行,并且可以轻松地与其他语言集成。
    在这里插入图片描述

Rust性能实战

针对于寻找字符串中两个重复字符的问题,如string=“ACCAGT”,重复字符是"CC",我们分别用rust跟python实现了两套算法。话不多说,各位看官先看下图:
算法性能对比
从图中可以看出,rust相比于python,算法性能上有十多倍的优势。
我们使用benchmark来对比各算法的时间,源码如下:

import re
import string
import random
import myrustlib # <--- Import the Rust implemented module (libmyrustlib.so).

# Python ZIP version
def count_doubles(val):
    total = 0
    # there is an improved version later on this post
    for c1, c2 in zip(val, val[1:]):
        if c1 == c2:
            total +=1
    return total

def count_doubles_once(val):
    total = 0
    chars = iter(val)
    c1 = next(chars)
    for c2 in chars:
        if c1 == c2:
            total += 1
        c1 = c2
    return total



# Python REGEXP version
double_re = re.compile(r'(?=(.)\1)')

def count_doubles_regex(val):
    return len(double_re.findall(val))


# Benchmark it
# generate 1M of random letters to test it
val = ''.join(random.choice(string.ascii_letters) for i in range(1000000))

def test_pure_python(benchmark):
    benchmark(count_doubles, val)

def test_pure_python_once(benchmark):
    benchmark(count_doubles_once, val)

def test_regex(benchmark):
    benchmark(count_doubles_regex, val)

def test_rust(benchmark): # <---- Benchmark the Rust version
    benchmark(myrustlib.count_doubles, val)

def test_rust_once(benchmark):
    benchmark(myrustlib.count_doubles_once, val)


以上代码包含了纯python的算法实现,下面贴出rust代码的实现,此处我们是采用rust生成动态库供python调用。

#[macro_use]
extern crate cpython;

use cpython::{Python, PyResult};
use std::collections:HashMap;

fn count_doubles(_py: Python, val: &str) -> PyResult<u64> {
    let mut total = 0u64;

    // There is an improved version later on this post
    for (c1, c2) in val.chars().zip(val.chars().skip(1)) {
        if c1 == c2 {
            total += 1;
        }
    }

    Ok(total)
}

fn count_doubles_once(_py: Python, val: &str) -> PyResult<u64> {
    let mut total = 0u64;
    let mut chars = val.chars();
    if let Some(mut c1) = chars.next() {
        for c2 in chars {
            if c1 == c2 {
                total += 1;
            }
            c1 = c2
        }
    }
    Ok(total)
}


py_module_initializer!(libmyrustlib, initlibmyrustlib, PyInit_myrustlib, |py, m | {
    try!(m.add(py, "__doc__", "This module is implemented in Rust"));
    try!(m.add(py, "count_doubles", py_fn!(py, count_doubles(val: &str))));
    try!(m.add(py, "count_doubles_once", py_fn!(py, count_doubles_once(val: &str))));
    Ok(())
});

需要注意的是,代码中使用cpython,我们需要在Cargo.toml文件中加入该依赖。

[package]
name = "pyext-myrustlib"
version = "0.1.0"
authors = ["Yang Pei <solroyail@gmail.com>"]

[lib]
name = "myrustlib"
crate-type = ["dylib"]

[dependencies.cpython]
version = "0.1"
features = ["extension-module"]

至此,代码已经完成啦。从以上可以看出来,Rust相比于Python语言的性能优势还是很大的。接下来我会针对于Rust的并发,继续跟C++,以及Python的多进程并发之间的对比。作为一名Rust初学者,纯以此文记录以及分享。
注:以上代码出自Red Hat社区的一篇博,原文链接如下Use Rust Speed Up Your Python

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值