如果我有三个单独的值,它们都可以容纳 32 位,那么使用 uint 来存储它们是否有意义?

StackOverflow https://stackoverflow.com/questions/3587593

我的意思是,假设我有一个 struct 来表示一些数据,它看起来像这样:

struct LilStruct
{
    public readonly short A;
    public readonly byte B;
    public readonly byte C;

    public LilStruct(short a, byte b, byte c)
    {
        A = a;
        B = b;
        C = c;
    }
}

A short 和两个 byte 值都可以装入 32 位。我想知道(出于对齐目的、性能等目的)以以下格式存储这些数据是否真的有意义:

struct LilStruct
{
    private readonly uint _value;

    public LilStruct(short a, byte b, byte c)
    {
        _value = ((uint)a << 16) | ((uint)b << 8) | (uint)c;
    }

    public int A
    {
        get { return (int)(_value >> 16); }
    }

    public int B
    {
        get { return (int)(_value >> 8) & 0x000000FF; }
    }

    public int C
    {
        get { return (int)(_value & 0x000000FF); }
    }
}

这毫无意义吗?有什么好处/缺点?

有帮助吗?

解决方案

在.net中,当您要使用 struct 无论如何,您也可以用 StructLayoutAttribute 像这样:

[StructLayout(LayoutKind.Sequential, Pack=1)]
struct LilStruct
{
    public readonly short A;
    public readonly byte B;
    public readonly byte C;

    public LilStruct(short a, byte b, byte c)
    {
        A = a;
        B = b;
        C = c;
    }
}

这将具有依次布置字段的效果,例如字段 B 将从偏移16开始。

值为1的值 Pack 意味着该字段在 byte 边界。

其他提示

您只应该考虑将多个值挤入UINT中,如果这些值彼此紧密绑定,通常是一起通过,并且从不或很少彼此独立地修改。与仅存储三个字节相比,解开和重新包装UINT以修改其值的成本使其非常昂贵(以代码尺寸和执行时间为单位)。

当执行总共10K字节的RAM时,这样的包装可能值得,因为内存比执行速度更宝贵。在普通的台式电脑甚至手机设备上,此包装可能不值得。

您可以遵守结构的定义,并应用 structlayout 属性 structlayoutattribute.pack 值为1。但是实际上,您可能会以访问速度为代价节省一些内存,因为这种方式不会以最有效的访问方式以内存为内存。编译器通常会以有效访问的方式布置内存,并且不会自动破坏过多的内存。

这种方法至少要比您提出的位转换方法保持更易于理解(实际上可能与机器代码编译器从字节代码生成的相似)。

您将遇到的是在内存数据对象的大小和处理成本之间的简单权衡。如果记忆是一个真正的问题,那么向机器上扔更多的RAM可能会更便宜。

在某些情况下,将内容塞入整数是值得的。单独的存储空间通常不是一个很好的理由,但如果这些值要一起使用,例如字典的键,字典(整数,无论​​)将比字典(某些结构,无论)快得多。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top