Rust 为什么我们使用掩码来剪切字节?

Rust 为什么我们使用掩码来剪切字节?,rust,Rust,所以我猜这是一个相当愚蠢的问题,但我自己无法找到答案 几天前,我必须创建一个返回无符号整数的强字节的函数。在网上做了一些研究之后,我想到了这个: fn strong_byte(num: u32) -> u8 { ((num >> 24) & 0xFF) as u8 } fn strong_byte(num: u32) -> u8 { (num << 24 >> 24) as u8 } 但在再次搜索一段时间后,我也发现了这个: f

所以我猜这是一个相当愚蠢的问题,但我自己无法找到答案

几天前,我必须创建一个返回无符号整数的强字节的函数。在网上做了一些研究之后,我想到了这个:

fn strong_byte(num: u32) -> u8 {
  ((num >> 24) & 0xFF) as u8
}
fn strong_byte(num: u32) -> u8 {
  (num << 24 >> 24) as u8
}
但在再次搜索一段时间后,我也发现了这个:

fn strong_byte(num: u32) -> u8 {
  ((num >> 24) & 0xFF) as u8
}
fn strong_byte(num: u32) -> u8 {
  (num << 24 >> 24) as u8
}
fn强字节(num:u32)->u8{
(数量>24)为u8
}

所以我想知道哪种形式更有效?我试图找到显示左移位和位掩码性能的基准,但没有找到任何结果

我知道第一种语法是目前为止使用最多的,但我不明白为什么第二种不是

学分也归其他人所有,请参见问题下方的评论

术语 什么是强字节?您应该使用(LSB)或(MSB)

你的职能 我在名称中添加了
\u1
\u2
后缀,只是为了区分它们

fn强字节(num:u32)->u8{
((数字>>24)和0xFF)作为u8
}
fn强字节(num:u32)->u8{
(数量>24)为u8
}
这两个函数做不同的事情。猜猜…的输出是什么

fn main(){
println!(“{}”,强字节_1(255));
println!(“{}”,强字节2(255));
}
。。。是<代码>\u 1返回
0
\u 2
返回
255
\u 1
返回MSB,
\u 2
返回LSB。如果你想比较它们,你必须修正它们

而且
strong\u byte\u 1
实现包含不必要的位掩码<代码>(num>>24)作为u8等于
(num>>24)作为u8
。检查Shepmaster在这里。
>
操作包含脚注:

有符号整数类型的算术右移,无符号整数类型的逻辑右移

u32
为无符号->逻辑右移(请参阅),这意味着:

0b11111111000000000000000000000000 >> 1 == 0b01111111100000000000000000000000
0b01111111100000000000000000000000 >> 1 == 0b00111111110000000000000000000000
0b00111111110000000000000000000000 >> 1 == 0b00011111111000000000000000000000
...
0b00000000000000000000000111111110 >> 1 == 0b00000000000000000000000011111111
LSB 让我们重写它们,这样它们都会返回LSB

fn lsb_1(编号:u32)->u8{
(num&0xFF)作为u8
}
fn lsb_2(编号:u32)->u8{
(数量>24)为u8
}
还有什么更有效

锈蚀1.36和选择等级=0 锈蚀1.36.0和选择等级=1 MSB
fn msb(num:u32)->u8{
(数字>>24)作为u8
}
锈蚀1.36.0和选择等级=0 锈蚀1.36.0和选择等级=1 结论 还有什么更有效?查看编译器输出(汇编),查阅目标体系结构文档等。您使用的编译器是什么?哪个版本?你的目标架构是什么?换句话说,你的问题太宽泛了

上面提到的是一个很好的工具,用于检查编译器输出是什么


一般来说,你应该完成你的程序,让它工作,然后优化。你的程序将做很多其他的事情,它将包含更多的瓶颈。测量、优化、回滚、优化、测量、提交。。。但要用最终产品来做,而不仅仅是简单的例行程序。你可以花费大量的时间在过早的(因此毫无用处的)优化上。然后,您会发现您优化了一个例程,但您的程序正在等待其他程序(网络,…),在其他地方有问题,…

这些程序做的不是同一件事。第一个返回
num
的最高有效字节。第二个返回
num
的最低有效字节“所以我想知道哪种形式的性能更高?”对于这样一个常见而琐碎的事情,如果有更好的方法,LLVM会对此进行优化。此外,在第一个示例中,掩码完全没有必要,
(num>>24)任何32位整数的&0xFF
==
num>>24
。如果将第一个示例修改为
num&0xFF
,则问题是有意义的,因为它们做相同的事情。但“强字节”不是一个常用术语;我会说“最低有效字节”。回答有关
num&0xFF
num>24
的问题:在
-C opt level=0
时,lsb\u移位速度要慢得多。在
-C opt level=1
时,它们是相同的,在更高的优化级别时,它们被合并到单个函数中。
example::msb:
        sub     rsp, 4
        shr     edi, 24
        mov     dword ptr [rsp], edi
        mov     eax, dword ptr [rsp]
        mov     cl, al
        mov     al, cl
        add     rsp, 4
        ret
example::msb:
        mov     eax, edi
        shr     eax, 24
        ret