CRust学习笔记:声明宏

电子说

1.2w人已加入

描述

本系列文章是Jon Gjengset发布的CRust of Rust系列视频的学习笔记,CRust of Rust是一系列持续更新的Rust中级教程。

在这篇文章中,我们将接着上一篇文章对avec!宏做性能优化。

先看一下已经写好的代码:

 1#[macro_export]
 2macro_rules! avec {
 3   ......
 4    ($element: expr; $count: expr) => {{
 5            let mut vs = Vec::new();
 6            let x = $element;
 7            for _ in 0..$count {
 8                vs.push(x.clone());
 9            }
10            vs
11        }};
12}

 

在第5行,我们创建了一个空的Vector,然后在第8行进行了一堆的push操作。

假设我们有1024个元素要放入到Vector中,那就进行了1024次push操作,就会导致在堆内存上对Vector进行多次重新分配。这是因为在 vector 增加新元素时,如果没有足够的空间就会要求分配大小是原内存2倍的新内存,并将老的元素拷贝到新的空间中,再销毁旧内存中的数据。

第一个需要改进的地方是:将创建空Vector的语法Vec::new()改成Vec::with_capacity(count),根据count大小预先分配内存空间,这样就避免了一堆的内存重新分配操作。

 1#[macro_export]
 2macro_rules! avec {
 3   ......
 4    ($element: expr; $count: expr) => {{
 5            let count = $count;
 6            let mut vs = Vec::with_capacity(count);
 7            let x = $element;
 8            for _ in 0..count {
 9                vs.push(x.clone());
10            }
11            vs
12        }};
13}
  第二个需要改进的地方是push,尽管已经预先分配了内存空间,但是每次执行push操作后,指向元素的指针地址都会增长,都会进行边界检查,这是不需要的。修改如下:
 1#[macro_export]
 2macro_rules! avec {
 3   ......
 4    ($element: expr; $count: expr) => {{
 5            let count = $count;
 6            let mut vs = Vec::with_capacity(count);
 7            vs.extend(std::repeat($element).take(count));
 8            vs
 9        }};
10}
 

 

我们使用Vector的extend方法,参数需要一个iterator,我们使用了标准库的std::repeat函数,它会把element元素进行clone。使用extend方法的好处是只会对iterator的范围进行一次边界检查,这样就更加高效。

我们也可以使用Vector的resize方法:

 1#[macro_export]
 2macro_rules! avec {
 3   ......
 4    ($element: expr; $count: expr) => {{
 5            // let count = $count;
 6            // let mut vs = Vec::with_capacity(count);
 7            // vs.extend(std::repeat($element).take(count));
 8            let mut vs = Vec::new();
 9            vs.resize($count, $element);
10            vs
11        }};
12}
至此,关于Rust的声明宏就学习完了。  

  审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分