坏蛋Dan
知乎@坏蛋Dan
发布时间:2024.1.4

前言

昨天我们学了Iterator迭代器

坏蛋Dan:rust基础学习--day30

今天我们来用所学的知识优化下之前写的那个minigrep

坏蛋Dan:rust基础学习--day28


优化前的代码


优化

还记得我们怎么把args里的参数放到Config实例中的吗?官方推荐的是clone复制一份数据出来.而我这里用的则是生命周期.

其中的区别是可维护性和性能 。

我当时也是推荐的clone,不过还是用生命周期来写,毕竟是在学习阶段.

扯远了,回到代码中.

优化点1: 直接获取迭代器中的数据

env::args()返回的是一个迭代器,那么我们完全可以从迭代器里获取数据.

来改下我们的lib.rs中代码

然后再来改下main函数

然后终端重新输入指令

可以看到使用迭代器我们省去了生命周期或者clone方法.

这样既好维护又不会失去性能.


优化点2: 直接使用filter

我们是通过&str.contains方法来判断是否存在匹配项的,其实lines返回的也是一个迭代器,我们完全可以使用filter顺便过滤了.

额,有点长了,因为我这里还需要把这个匹配到的数据传出去,所以多了一步map转换类型以及获取所有权.


循环(loop)还是迭代(iterate)

在学迭代器之前,我们遍历都是通过for/while/loop的方式,而学完迭代器之后我们又多了种遍历的方式.

那么loopiterate之间哪个更快呢?

为了回答这个问题,rust官方做了一个比较,在一本书*The Adventures of Sherlock Holmes*[3]里找一个词,用找到这个词(所有,并不是找到一个就停止)所用的时间来判断.

可以明显看到迭代器所用的时间少很多.

迭代器是rust中少有的*zero-cost abstractions,*也就是零成本抽象概念,换句话说就是不会对runtime有任何负担,在编译阶段就被转换成类似我们手动重复写的低级代码了

再来看个例子

这是一段音频解码器的解码算法,基于线性预测来计算,根据之前收集到的数据来线性预测将来的值.

这里有三个变量

  1. coefficients,它是一个数组, 有12个元素
  2. buffer,他也是一个数组,个数未知.
  3. qlp_shift,是一个i16类型的整数.

三者做的运算

coefficientsbuffer中第i-12..i个进行zip,什么是zip呢?就像拉链一样

来看下zip的例子,它返回一个新的迭代器,所以它是一个迭代器适配器.

然后我们来看下c的数据

可以看到它返回的迭代器item是一个元组包裹着两个迭代器里的item.

然后将元组里的元素相乘,之后再把迭代器里的数据相加.

sum方法前面说过了,就是将迭代器里的元素相加返回一个结果.

最后再向右偏移qlp_shift个位置.

额,好像和我们的题目没啥关系?

其实还没说到点上,对于这样的代码,rust在编译阶段不会去遍历,而是重复12次,因为这里只有12个元素,就像是我们去手写一样.

rust开发团队称之为unrolls.也就是展开.

通过两个小例子,rust团队是想说: 尽情的用迭代器吧,不用害怕.

总结

今天我们优化了下之前写的minigrep小工具,然后又看了下迭代器和循环之间的区别,了解迭代器的部分底层相关知识.

参考

  1. ^rust-13.3-improving-our-I/O-project https://doc.rust-lang.org/book/ch13-03-improving-our-io-project.html#improving-our-io-project
  2. ^rust-13.4-comparing-performance: Loops vs Iterators https://doc.rust-lang.org/book/ch13-04-performance.html#comparing-performance-loops-vs-iterators
  3. ^the adventures of sherlock holmes https://www.bing.com/ck/a?!&&p=dd651b5613da6ee2JmltdHM9MTY3MjA5OTIwMCZpZ3VpZD0xMmFlZWUwMi0wMDgyLTZiYTgtM2ZmNy1mZTY2MDQ4MjY5ZWQmaW5zaWQ9NTI3NQ&ptn=3&hsh=3&fclid=12aeee02-0082-6ba8-3ff7-fe66048269ed&psq=the+adventures+of+sherlock+holmes&u=a1aHR0cHM6Ly9wb2RjYXN0cy5hcHBsZS5jb20vdXMvcG9kY2FzdC90aGUtYWR2ZW50dXJlcy1vZi1zaGVybG9jay1ob2xtZXMtYnktc2lyLWFydGh1ci1jb25hbi1kb3lsZS9pZDcyNzQwNTE0OQ&ntb=1

发布于 2022-12-28 15:21・IP 属地广东