u8 作为 i32 与 i32::from_be_bytes([u8;4])
u8 as i32 vs i32::from_be_bytes([u8;4])
总自行车脱落,但我想知道
的相对效率
let mut buf = [0u8];
input.read(&mut buf)?;
Ok(buf[0] as i32)
对
let mut buf = [0u8; 4];
input.read(&mut buf[3..4])?;
Ok(i32::from_be_bytes(buf))
即使出于审美原因,也很难在它们之间做出选择,因为孤立地我更喜欢第一组代码,但我有并行方法来读取遵循后一种模式的 16、24 和 32 位整数数据使其在上下文中更具吸引力。
假设您打算存储负值,您的代码将无法正确处理有符号整数。如果一个文件有一个 i8
和值 -1
(0xFF
),你将把它读作一个 u8
和值 255
并转换为 i32
,产生错误的值(参见 this playground)。如果您希望值正确返回,您需要执行符号扩展。
我建议使用 byteorder crate,它具有以字节序感知方式正确读取整数的方法。生成的代码看起来像
use byteorder::{LE, ReadBytesExt};
reader.read_i8()? as i32;
reader.read_i16::<BE>()? as i32;
reader.read_i24::<BE>()? as i32;
reader.read_i32::<BE>()?;
看起来第一个会更有效率一些。它使用 movzx
而不是 bswap
。
你可以在这里看到:
https://rust.godbolt.org/z/WxW1bj4Eh
编译器很难将 bswap
转换为 movzx
,因为它需要通过读取才能理解缓冲区的其余部分为 0。
总自行车脱落,但我想知道
的相对效率let mut buf = [0u8];
input.read(&mut buf)?;
Ok(buf[0] as i32)
对
let mut buf = [0u8; 4];
input.read(&mut buf[3..4])?;
Ok(i32::from_be_bytes(buf))
即使出于审美原因,也很难在它们之间做出选择,因为孤立地我更喜欢第一组代码,但我有并行方法来读取遵循后一种模式的 16、24 和 32 位整数数据使其在上下文中更具吸引力。
假设您打算存储负值,您的代码将无法正确处理有符号整数。如果一个文件有一个 i8
和值 -1
(0xFF
),你将把它读作一个 u8
和值 255
并转换为 i32
,产生错误的值(参见 this playground)。如果您希望值正确返回,您需要执行符号扩展。
我建议使用 byteorder crate,它具有以字节序感知方式正确读取整数的方法。生成的代码看起来像
use byteorder::{LE, ReadBytesExt};
reader.read_i8()? as i32;
reader.read_i16::<BE>()? as i32;
reader.read_i24::<BE>()? as i32;
reader.read_i32::<BE>()?;
看起来第一个会更有效率一些。它使用 movzx
而不是 bswap
。
你可以在这里看到: https://rust.godbolt.org/z/WxW1bj4Eh
编译器很难将 bswap
转换为 movzx
,因为它需要通过读取才能理解缓冲区的其余部分为 0。