rust - 切片的安全 memset 相当于什么?
问题描述
在许多情况下,我需要清除缓冲区区域或将切片设置为某个值。这样做的本机推荐方式是什么?
这是无效的 Rust,但我想做类似的事情:
let mut some_buffer = vec![0u8; 100];
buffer[10..20].set(0xFF)
我可以使用 for 循环,但我觉得我错过了一些东西,因为我是 Rust 的新手。
在 C++ 中,我会做类似的事情:
std::array<int,6> foobar;
foobar.fill(5);
在 Python 中,它会是类似的:
tmp = np.zeros(10)
tmp[3:6]=2
解决方案
你不是唯一一个。存在同一事物的功能请求/ RFC:
但是,您是本末倒置。你真的关心它的调用memset
吗?我猜不是,只是它很有效。Rust 的一大吸引力是编译器可以在构建时“丢弃”许多抽象。例如,当某些 CPU 指令会做同样的事情时,为什么还要调用函数呢?
pub fn thing(buffer: &mut [u8]) {
for i in &mut buffer[10..20] { *i = 42 }
}
playground::thing:
pushq %rax
cmpq $19, %rsi
jbe .LBB0_1
movabsq $3038287259199220266, %rax
movq %rax, 10(%rdi)
movw $10794, 18(%rdi)
popq %rax
retq
.LBB0_1:
movl $20, %edi
callq core::slice::slice_index_len_fail@PLT
ud2
pub fn thing(buffer: &mut [u8]) {
for i in &mut buffer[10..200] { *i = 99 }
}
.LCPI0_0:
.zero 16,99
playground::thing:
pushq %rax
cmpq $199, %rsi
jbe .LBB0_1
movaps .LCPI0_0(%rip), %xmm0
movups %xmm0, 184(%rdi)
movups %xmm0, 170(%rdi)
movups %xmm0, 154(%rdi)
movups %xmm0, 138(%rdi)
movups %xmm0, 122(%rdi)
movups %xmm0, 106(%rdi)
movups %xmm0, 90(%rdi)
movups %xmm0, 74(%rdi)
movups %xmm0, 58(%rdi)
movups %xmm0, 42(%rdi)
movups %xmm0, 26(%rdi)
movups %xmm0, 10(%rdi)
popq %rax
retq
.LBB0_1:
movl $200, %edi
callq core::slice::slice_index_len_fail@PLT
ud2
正如kazemakase 指出的那样,当设置区域变得“足够大”时,优化器会切换到 usingmemset
而不是内联指令:
pub fn thing(buffer: &mut [u8]) {
for i in &mut buffer[11..499] { *i = 240 }
}
playground::thing:
pushq %rax
cmpq $498, %rsi
jbe .LBB0_1
addq $11, %rdi
movl $240, %esi
movl $488, %edx
callq memset@PLT
popq %rax
retq
.LBB0_1:
movl $499, %edi
callq core::slice::slice_index_len_fail@PLT
ud2
如果您愿意,可以将此函数包装在扩展特征中:
trait FillExt<T> {
fn fill(&mut self, v: T);
}
impl FillExt<u8> for [u8] {
fn fill(&mut self, v: u8) {
for i in self {
*i = v
}
}
}
pub fn thing(buffer: &mut [u8], val: u8) {
buffer[10..20].fill(val)
}
也可以看看:
推荐阅读
- r - R 在 2 个列表中的匹配元素上迭代一个函数
- flutter - 在flutter中成功认证后如何重定向到下一页
- kubernetes - 基于 CPU 的水平 pod 自动缩放在 Kubernetes 集群中不起作用
- python - 有没有办法完全阻止用户表单退出 pygame 窗口?
- c# - 第一次部署 ASP.NET web api,遇到'/'错误
- java - Jackson XmlMapper 如何用动态标签名称序列化列表
- javascript - 在我使用 document.location 后等待页面加载
- c - 自定义shell多个管道成功,但没有输出到stdout
- javascript - 如何使用接口中的键克隆对象
- php - 如何使用 mpdf 适合一页?