零成本名符其实
#zerocost #arc_swap
作者在实现一个库arc-swap,允许存储[Arc]
,并且可以原子性地交换它。类似于RwLock<Arc>
,但要更快且永远不会阻塞。此库被应用于作者的另外一个信号处理的库中signal-hook。
作者在实现这些库的过程中,仔细查看了Rust编译器生成的汇编代码,发现编译器做了很多额外的工作来展开抽象,但最终那些多余的操作都被抛弃了,只剩下最关键的一两条汇编指令。
Rust如何帮助Kentik提升性能
#kentik #hooray
美国的网络大数据分析公司Kentik使用Rust优化了网络分析平台的性能。该公司软件工程师声称:
Rust是Kentik每秒摄取来自互联网百万分之一的流量(十亿比特(Gigabits)/千万亿(Petabit/s))的重要部分,并且每天存储100TB的网络流数据。我们平台的性能和可靠性依赖于Rust编写的软件,我们受益于crates.io上可用的强大的开源库生态系统。
在网络数据解析方面,使用nom,实现了高性能的零Copy解析器,对DHCP、DNS和HTTP等数据进行了高性能的解码。在数据存储方面,使用Rust编写了新的后端磁盘存储格式,可提供更高的性能和存储密度。在查询层也使用Rust编写的HyperLogLog扩展。Rust的性能和低内存使用是这里的一个关键。
这些组件和C-API一起分发,并链接到了分布式存储引擎的各个部分。Kentik大多数后端都是用Go来编写,但是Go写的共享库很大,包含了完整运行时和GC等。而且Go在运行时初始化会产生很多线程,在链接到静态二进制文件还会导致运行时的段错误。所以他们也为此增加了很多补丁,但这并不是对Go的攻击,反而,他们对Go还算满意。相比于Go,Rust更容易动态和静态链接,因为没有运行时和GC,也没有从C调用Rust函数的开销。
所以,你如果对Rust感兴趣,赶紧试试吧。
「长文」那些Rust不允许你干的事
#rust #lifetime #borrow #mutable
本文罗列了Rust中可变系统和借用检查不允许开发者做的事情,并讨论了当前行为的理由,以及可能的解决方法。
文章较长,还需要耐心阅读。我有时间会翻译,也招募志愿者来翻译此文,可以一起协作。
「项目」Rust实现的寄存器式虚拟机
#vm #register_based #jazz
大多数语言vm都是栈式VM,之前介绍的一些VM实现也都是栈式。今天第一次见寄存器式VM的Rust实现。
Android虚拟机Dalvik就是寄存器式VM,可以参考Dalvik的相关资料来了解寄存器式VM的工作机制。
感兴趣的可以关注下。
「工具」 按时区查看日志的工具
#tail #tztail #timezone
「官方」await语法方面的进展
#async #await #rust
官方核心成员withoutboat的新博文。
截止目前,await语法有一个未解决的问题是await的最终语法。当前的实现是await!宏。 无船同志在这篇文章里建议在不久的将来引入await关键字。
目前使用await!宏是因为await
和?
操作之间有一个优先级的问题。考虑下面代码:
let response = await http::get(url)?;
http::get
函数的返回类型基本等价于impl Future<Output = io::Result<Response>>
,也就是说,该函数会返回一个成功或失败的Future。这意味着你想要的行为是这样的:
- 首先,await那个Future,计算其输出
io::Result<Response>
。 - 其次,使用
?
来对result解包,如果没有成功则提前返回错误。
但事实上,当你看到这段代码的时候,你的直觉是?
操作比await
优先,因为它离http::get
函数更近。这个例子很常见,在I/O操作中经常经常可能需要返回错误。这里就存在着优先顺序的冲突。
优先问题有以下几种潜在的解决方案:
- await!宏是一种既定方案。
- 默认await优先。用户可以使用括号来改变优先级,比如
await (function()?)
。但是这种默认的优先级语法会让开发者违反直觉。 - 默认
?
优先,倒是符合直觉。但是用户需要为await返回错误则需要写成(await function())?
。但是用户在异步开发的时候可能会经常写这种带括号的代码。 - 引入某种后缀语法,比如
await? function()
,但这个很怪。 - 总是使用分隔符号。比如
await {}
,类似于unsafe {}
。
无船同志认为上面最靠谱的,还是最后一种方案,使用分隔符。这样也有利用兼容之前的宏写法。他也建议稳定这种await语法。并且文章中也透露,将在2019年3月初的1.33版本稳定future-rs 0.3。
Rust Flow: 数据流与Rust中方法调用链
#rust #flow
本文探讨了Rust对实现方法调用链的支持。
观点:Rust强烈建议使用方法链来简明地表达意图和程序流,提供了能够通过使用方法调用而不是分支和循环结构来产生控制流效果的类型和方法,这些可以用来使代码更易于阅读和修改。
如何使用-Zprint-type-sizes
获取Rust类型大小
#rust #type_size
在编译时使用-Zprint-type-sizes
可以得到比std::mem::size_of
方法更加详细的信息。
enum E {
A,
B(i32),
C(u64, u8, u64, u8),
D(Vec<u32>),
}
命令:
$ RUSTC_BOOTSTRAP=1 rustc -Zprint-type-sizes a.rs
输出:
print-type-size type: `E`: 32 bytes, alignment: 8 bytes
print-type-size discriminant: 1 bytes
print-type-size variant `A`: 0 bytes
print-type-size variant `B`: 7 bytes
print-type-size padding: 3 bytes
print-type-size field `.0`: 4 bytes, alignment: 4 bytes
print-type-size variant `C`: 23 bytes
print-type-size field `.1`: 1 bytes
print-type-size field `.3`: 1 bytes
print-type-size padding: 5 bytes
print-type-size field `.0`: 8 bytes, alignment: 8 bytes
print-type-size field `.2`: 8 bytes
print-type-size variant `D`: 31 bytes
print-type-size padding: 7 bytes
print-type-size field `.0`: 24 bytes, alignment: 8 bytes
但只能在Rust Nightly版本下使用。
每日新闻订阅地址:
欢迎通过GitHub issues投稿。
评论区
写评论这不是很直观吗
这个await的例子把我搞蒙圈了