vector - 检查 Vec看看它是否全为零?
问题描述
我有许多 4KiB 缓冲区,它们有 50% 的机会只包含零值。非零缓冲区通常在缓冲区的早期有一个非零字节。
fn is_zero(buf: &Vec<u8>) -> bool {
for byte in buf.into_iter() {
if *byte != 0 {
return false;
}
}
return true;
}
这是检查 Rust 的一种高效方式--release
吗?(我正在处理许多 GB 的数据。)
(在 C 版本中,我unsigned long long
在检查之前将缓冲区转换为。考虑到 SSE 等,这可能不是我能做的最好的事情。)
解决方案
您align_to
可以将切片 ofu8
转换为 切片u128
,从而使比较更有效:
fn is_zero(buf: &[u8]) -> bool {
let (prefix, aligned, suffix) = unsafe { buf.align_to::<u128>() };
prefix.iter().all(|&x| x == 0)
&& suffix.iter().all(|&x| x == 0)
&& aligned.iter().all(|&x| x == 0)
}
在我的机器上运行一个简单的基准测试显示了 16 倍的性能提升!
#![feature(test)]
extern crate test;
fn v() -> Vec<u8> {
std::iter::repeat(0).take(1000000).collect()
}
fn is_zero(buf: &[u8]) -> bool {
buf.into_iter().all(|&b| b == 0)
}
fn is_zero_aligned(buf: &[u8]) -> bool {
let (prefix, aligned, suffix) = unsafe { buf.align_to::<u128>() };
prefix.iter().all(|&x| x == 0)
&& suffix.iter().all(|&x| x == 0)
&& aligned.iter().all(|&x| x == 0)
}
#[bench]
fn bench_is_zero(b: &mut test::Bencher) {
let v = test::black_box(v());
b.iter(|| is_zero(&v[..]))
}
#[bench]
fn bench_is_zero_aligned(b: &mut test::Bencher) {
let v = test::black_box(v());
b.iter(|| is_zero_aligned(&v[..]))
}
running 2 tests
test tests::bench_is_zero ... bench: 455,975 ns/iter (+/- 414)
test tests::bench_is_zero_aligned ... bench: 28,615 ns/iter (+/- 116)
根据您的机器,不同的整数类型 ( u64
) 可能会产生更好的性能。
感谢 Rust discord 服务器上的@Globi 提供的想法
推荐阅读
- r - 因素变量到工作日
- django - TemplateDoesNotExist at / in django
- ssl - 从 Windows 服务器禁用 TLS 1.0
- amazon-ec2 - 禁止 ec2 ssh 密钥对登录,但允许使用特殊的 ssh 密钥登录
- java - 当我在单击某些按钮时调用相同的对话框方法时,如何处理对话框的 UI
- c# - 使用 Google Speech to Text API 从 Web 应用程序中的麦克风捕获实时音频
- c++ - C ++中的硒?
- python - (TypeError: cannot unpack non-iterable int object) for inversion counter使用归并排序
- python - 有没有办法在 discord.py 中一次获得多个命令的剩余冷却时间?
- javascript - 在 aem 中获取其他组件的值