这是 Facebook for Develpers 网站出的Rust Nibbles系列文章,介绍 facebook 开源的各种 Rust 库。
Gazebo 是 facebook 工程师 编写的基础库,Gazebo以独立模块的形式包含了一系列经过测试的Rust实用程序。这篇文章是介绍了 Gazebo 中的 Dupe trait 。
在Rust中,有两个用于 "复制 "一个值的相关特性--Copy和Clone。
在Gazebo中引入了第三个类似的trait,称之为Dupe,它可以在Gazebo Prelude中使用。(dupe 有复制物品/复制底片的意思)。
Copy 是 编译器的自动行为,复制成本也不高。而 Clone 则不然。为了降低 Clone 的成本,一般可以使用 Arc,但是 Arc 使得代码阅读成本提升。比如 let xs = ys.clone();
,你可能需要查看大量上下文来弄清是 调用了 Clone 还是 Arc 。当然你可以使用 let xs = Arc::clone(ys)
来提升可读性,但缺点是,它破坏了抽象。
所以,Gazebo 中引入了 Dupe trait, let xs = ys.dupe()
。
rust use gazebo::prelude::*; #[derive(Clone, Dupe)] struct MyArc(Arc);
看了一下实现源码:https://github.com/facebookincubator/gazebo/blob/master/gazebo/src/dupe.rs
rust pub trait Dupe: Clone { fn dupe(&self) -> Self { self.clone() } } 看上去和 Clone 很像,但它仅在 常量时或零分配下可用,比如 Arc。因为 Dupe 只给这些类型实现了。
https://developers.facebook.com/blog/post/2021/07/06/rust-nibbles-gazebo-dupe/
Forward : Rust 视界
Zenoh 性能提升的故事| 漫游在 Rust 异步仙境
在 Rust Maginze 月刊第四期中介绍过 Zenoh : 开源产品 | eclipse zenoh 助力雾计算和边缘计算
eclipse zenoh (读:/zeno/ ) ,提供了零开销的Pub/Sub、Store/Query 和 计算。
zenoh 统一了 动态/静止/使用中的数据并提供计算结果。它颇有分寸地将传统的Pub/Sub与地理分布的存储、查询和计算融合在一起,同时保留了远远超出任何主流协议栈的时间和空间效率水平。
官网是 zenoh.io 。
GitHub代码仓库 eclipse-zenoh/zenoh 。
2020 年 12 月 Eclipse Edge Native 工作组启动,并将 Zenoh 引入 Eclipse 。并用 Rust 对 zenoh 进行重写。
在本文中,Zenoh 团队剖析了他们如何改进让异步性能提升一倍。
- 8字节payload 时超过3.5M msg/s
- 1Mb payload 时超过 45Gb/s
- 在 backlogged 场景下,延迟低至 35 微秒
该团队如何做到的呢?
一:准备工作
- 准备测试环境,以便获得可复现的结果。因为很多外部因素可能会影响代码性能,这是为了排除这些干扰。这有个非常棒的指南:https://easyperf.net/blog/2019/08/02/Perf-measurement-environment-on-Linux
- 彻底阅读 《Rust 性能手册》。我们发现它对Rust的性能技巧和诀窍以及剖析技术都很有见地。另外,还有一篇关于如何在Rust中编写高性能代码的博客也是不错的参考。
二:寻找性能热点(hotspots)
- 我们先使用 flamegraph 来生成火焰图,打算寻找 zenoh 中的异步性能热点。然而,异步使得火焰图相当难以阅读,因为异步调度器和future执行器基本上出现在火焰图中每一个地方。所以改变了性能剖析工具,开始使用 perf ,可以提供更清晰的热点图,尤其是序列化和反序列化方面。
- 改进了序列化/反序列化相关实现,性能直接提升 100% 。但是这种改进在吞吐量测试中没有反映出来。
三:堆分配还是栈分配?
zenoh 团队 一直避免在关键环节进行堆分配。用 valgrind 仔细检查后发现,并没有不必要的堆分配,缓存未命中率也不高。因此该团队开始检查 栈分配的问题,利用 Rust 编译器的一个 flag (仅在 Rust Nightly 可用)来验证一个数据结构多大以及它的内存对齐方式。
rust $ RUSTFLAGS=-Zprint-type-sizes cargo build --release 用这种方式来编译 zenoh 即可。输出:
rust print-type-size type: net::protocol::proto::msg::Data
: 304 bytes, alignment: 8 bytes print-type-size field .key
: 40 bytes print-type-size field .data_info
: 168 bytes print-type-size field .payload
: 96 bytes
异步数据结构也会这样打印出来。然后该团队发现了一个痛苦的事实:
- 异步 future,一旦被编译,就会在栈中占用几十 KB 的空间。每次有消息需要通过网络发送,就会调用这些 futures。
- 因为zenoh广泛使用异步,所以现在导致 栈太深太大,给内存带来很大压力。
- 经过思考,该团队将 异步代码隔离在特定的部分,尤其是网络交互部分,而其他部分则转为使用同步。由此来平衡 同步和异步,汲取了两个世界的优点。大幅减少了栈内存的压力,带了巨大的性能提升。
四:性能测试结果
该团队性能测试环境为:AMD Ryzen 5800x,32GB内存,通过100Gb以太网连接,根据前面所说的性能测试环境配置指南配置好。
具体的性能测试图表,可以进一步查看文章。也可以关注 zenoh 团队的博客,因为他们性能优化还会继续。
https://zenoh.io/blog/2021-07-13-zenoh-performance-async/
Forward : Rust 视界
Rust Tauri Svelte 教程
随着 Rust 越来越受欢迎,越来越多的人想要学习它,我决定创建另一个主要针对初学者的教程。使用 Rust 创建桌面应用程序的方法很少,而 Tauri 绝对是一种可以让您制作漂亮的 UI(HTML/JS/CSS)并在后台利用 Rust 功能的方法。由于 Tauri 允许您选择任何前端框架(或不选择),因此我创建了一个使用 Svelte 和 Bootstrap(通过 Sveltestrap)的简单模板,为开发人员提供了一个很好的起点。为了演示如何使用它,我们将创建简单的密码生成器。
恰好我的实习项目Local Native
就是使用tauri-bundle
进行多平台打包的,说实话,用起来很丝滑,很简单易用,在此再次感谢tauri
团队!
Read More: https://jbarszczewski.com/rust-tauri-svelte-tutorial
使用基于 eBPF 的内存分析器将 TezEdge 节点的内存使用量减半
本文介绍了作者使用基于eBPF的内存分析器来优化Rust代码的事。
Read More: https://medium.com/tezedge/halving-the-tezedge-nodes-memory-usage-with-an-ebpf-based-memory-profiler-2bfd32f94f69
本周引语
代码语言:javascript复制Rust 新锈:呃,为什么编译器要阻止我做这些?太可怕了!
Rust 老锈:呃,为什么编译器不阻止我做这些!太可怕了!
– qDot 发表于 twitter
Read More:https://this-week-in-rust.org/blog/2021/07/14/this-week-in-rust-399/
中文:https://blog.budshome.com/budshome/rust-guan-fang-zhou-bao-399-qi-(2021-07-14)
--
From 日报小组 Cupnfish AlexZhang
感谢张老师提供的内容