本系列文章是Jon Gjengset发布的CRust of Rust系列视频的学习笔记,CRust of Rust是一系列持续更新的Rust中级教程。
在这篇文章中,我们将接着上一篇文章对avec!宏做性能优化。
先看一下已经写好的代码:
1#[macro_export]
2macro_rules!avec{
3......
4($element:expr;$count:expr)=>{{
5letmutvs=Vec::new();
6letx=$element;
7for_in0..$count{
8vs.push(x.clone());
9}
10vs
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)=>{{
5letcount=$count;
6letmutvs=Vec::with_capacity(count);
7letx=$element;
8for_in0..count{
9vs.push(x.clone());
10}
11vs
12}};
13}
第二个需要改进的地方是push,尽管已经预先分配了内存空间,但是每次执行push操作后,指向元素的指针地址都会增长,都会进行边界检查,这是不需要的。修改如下:
1#[macro_export]
2macro_rules!avec{
3......
4($element:expr;$count:expr)=>{{
5letcount=$count;
6letmutvs=Vec::with_capacity(count);
7vs.extend(std::repeat($element).take(count));
8vs
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//letcount=$count;
6//letmutvs=Vec::with_capacity(count);
7//vs.extend(std::repeat($element).take(count));
8letmutvs=Vec::new();
9vs.resize($count,$element);
10vs
11}};
12}
至此,关于Rust的声明宏就学习完了。
审核编辑:汤梓红
-
内存
+关注
关注
9文章
3173浏览量
76119 -
代码
+关注
关注
30文章
4941浏览量
73155 -
Rust
+关注
关注
1文章
240浏览量
7481
原文标题:CRust学习笔记:声明宏-3
文章出处:【微信号:Rust语言中文社区,微信公众号:Rust语言中文社区】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
请问关于C6000系列库中DISABLE ,DEFAULT这样的宏是在哪个头文件里声明的?
MCU学习笔记相关资料分享
MCU学习笔记_C语言基础

CRust学习笔记:声明宏
评论