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。