将字节打包到 u32 与将它们存储在 vec<u8> 中的性能差异?

问题描述

简介:

我很好奇将小数存储为位打包无符号整数与字节向量的性能差异(cpu 和内存使用情况)

示例

我将使用存储 RGBA 值的示例。它们是 4 个字节,因此很容易将它们存储为 u32
但是,将它们存储为 u8 类型的向量会更具可读性。


作为一个更详细的例子,假设我想存储和检索颜色 rgba(255,255)

这就是我将如何做这两种方法

// Bitpacked:
let i: u32 = 4278190335;
//binary is 11111111 00000000 00000000 11111111
//In reality I would most likely do something more similar to:
let i: u32 = 255 << 24 + 255; //i think this Syntax is right

// Vector:
let v: Vec<u8> = [255,255];

然后可以用

查询这两个红色值
i >> 24 
//or
&v[0]
//both expressions evaluate to 255 (i think. I'm really new to rust <3 )

问题 1

据我所知,v 的值必须存储在堆上,因此存在与此相关的性能成本。这些成本是否足以让比特打包变得值得?

问题 2

然后是两个表达式 i >> 24&v[0]。我不知道 Rust 在位移位与从堆中获取值的速度有多快。我会测试它,但我暂时无法访问安装了 Rust 的机器。有人可以立即了解这两种操作的缺点吗?

问题 3

最后,内存使用的区别是否简单到仅在堆栈上为 u32 存储 32 位与在堆栈上为指针 v 存储 64 位以及在指针上存储 32 位一样简单? v 的值的堆?

对不起,如果这个问题有点令人困惑

解决方法

使用 Vec 会更贵;正如您提到的,它将需要执行堆分配,并且访问也将进行边界检查。

也就是说,如果您改用数组 [u8; 4],与位打包 u32 表示相比的性能应该几乎相同。

实际上,请考虑以下简单示例:

pub fn get_red_bitpacked(i: u32) -> u8 {
    (i >> 24) as u8
}

pub fn get_red_array(v: [u8; 4]) -> u8 {
    v[3]
}

pub fn test_bits(colour: u8) -> u8 {
    let colour = colour as u32;
    let i = (colour << 24) + colour;
    get_red_bitpacked(i)
}

pub fn test_arr(colour: u8) -> u8 {
    let v = [colour,colour];
    get_red_array(v)
}

我查看了 Compiler Explorer,编译器认为 get_red_bitpackedget_red_array 完全相同:以至于它甚至没有为前者生成代码。这两个“测试”函数显然也针对完全相同的程序集进行了优化。

example::get_red_array:
        mov     eax,edi
        shr     eax,24
        ret

example::test_bits:
        mov     eax,edi
        ret

example::test_arr:
        mov     eax,edi
        ret

显然这个例子被编译器看穿了:为了进行适当的比较,你应该用实际代码进行基准测试。也就是说,我认为使用 Rust 时,u32[u8; 4] 对这些类型的操作的性能总体上应该是相同的。

,

tl;dr 使用结构:

struct Color {
    r: u8,g: u8,b: u8,a: u8,}

也许也可以使用 repr(packed)

它为您提供了世界上最好的东西,您可以为频道命名。

这些成本是否足以使比特包装值得?

堆分配具有巨大成本。

有人可以立即就这两种操作的缺点给出任何见解吗?

与分配内存相比,两者都是噪音。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...