我有许多4KiB的缓冲区,它们有50%的机会只包含零值。非零缓冲区通常在缓冲区早期具有非零字节。
fn is_zero(buf: &Vec<u8>) -> bool {
for byte in buf.into_iter() {
if *byte != 0 {
return false;
}
}
return true;
}
这是一种使用--release
签入Rust的高性能方法吗?(我正在处理许多GB的数据。
(In在C版本中,我在检查之前将缓冲区转换为unsigned long long
。这可能不是我能做的最好的,考虑到SSE等。
4条答案
按热度按时间yks3o0rb1#
您可以使用
align_to
将u8
的切片转换为u128
的切片,使比较更有效:在我的机器上运行一个简单的基准测试显示了16倍的性能增益!
根据您的计算机,不同的整数类型(
u64
)可能会产生更好的性能。bwleehnv2#
通过一次阅读
u64
,在我的笔记本电脑上使用byteorder
获得了4倍的加速。lib.rs
benches/benches.rs
bxjv4tth3#
下面的函数是纯保存 Rust:
具体来说,它使用
u128::from_be_bytes
函数将[u8; 16]
数组转换为u128
作为non-op,并使用TryInto
trait将适当长度的[u8]
转换为[u8; 16]
-其余部分相当简单。可以手动展开内部循环来转换它,但我怀疑这是否会成为一个显著的性能瓶颈,因为构成列表尾部的u8
不是16字节。根据处理器的不同,使用
u64
甚至u32
可能会更快,人们必须自己分析。byqmnocz4#
您可以使用rayon,这是一个数据并行库,看起来非常适合您的用例。用途:只需将
buf.iter()
更改为buf.par_iter()
,Rayon就会完成其余的工作:对于2000万个元素的矢量,人造丝显示出7倍的性能提升:
请注意,多线程的性能影响取决于工作负载(元素数量),较小的工作负载可能会受到负面影响。