整数数组或结构数组 - 哪个更好?

Mus*_*sis 5 .net c# memory rgb struct

在我的应用程序中,我将Bitmap数据存储在二维整数数组(int[,])中.要访问R,G和B值,我使用以下内容:

// read:
int i = _data[x, y];
byte B = (byte)(i >> 0);
byte G = (byte)(i >> 8);
byte R = (byte)(i >> 16);
// write:
_data[x, y] = BitConverter.ToInt32(new byte[] { B, G, R, 0 }, 0);
Run Code Online (Sandbox Code Playgroud)

我使用整数数组而不是实际数组,System.Drawing.Bitmap因为我的应用程序在Windows Mobile设备上运行,其中可用于创建位图的内存受到严重限制.

但是,我想知道,如果宣布这样的结构会更有意义:

public struct RGB
{
    public byte R;
    public byte G;
    public byte B;
}
Run Code Online (Sandbox Code Playgroud)

...然后使用数组RGB而不是数组int.这样我就可以轻松读取和写入单独的R,G和B值,而无需进行位移和BitConverter.我依旧记得以前几天关于byte变量在32位系统上进行块对齐的事情,所以byte实际上占用了4个字节的内存而不是1个(但这可能只是一个Visual Basic的东西).

使用结构数组(如RGB上面的示例)比使用整数数组更快,它会使用3/4内存还是内存的3倍内存?

Mar*_*ell 3

如果您关心的是速度,那么从技术上讲,我希望该int[]版本更快,因为有一个特定的 IL 指令用于int从数组中获取 an(请参阅 参考资料OpCodes.Ldelem_I4)。要执行自定义结构,它必须获取地址 ( OpCodes.Ldelema),然后复制结构 ( OpCodes.Ldobj) - 处理这两个步骤的类型元数据。

简而言之 - 该int方法应该有更好的优化。但这是微观优化——通常喜欢使代码更具可读性的版本。您可能会考虑使用自定义静态隐式转换运算符将结构编写为int您的结构 - 然后您可以拥有int[]并且仍然可以这样做:

MyColor col = intArr[12];
Run Code Online (Sandbox Code Playgroud)

(当然,它会在中间进行静态调用)

您也可以考虑使用联合,这样您就不需要进行大量的转换:

重要的是我还没有理智地检查过这方面的字节顺序;只需改变R/G/B的偏移即可改变它。

class Program
{
    static void Main()
    {
        int[] i = { -1 };
        RGB rgb = i[0];
    }
}
[StructLayout( LayoutKind.Explicit)]
public struct RGB
{
    public RGB(int value) {
        this.R = this.G = this.B = 0; this.Value = value;
    }
    [FieldOffset(0)]
    public int Value;
    [FieldOffset(2)]
    public byte R;
    [FieldOffset(1)]
    public byte G;
    [FieldOffset(0)]
    public byte B;

    public static implicit operator RGB(int value) {
        return new RGB(value);
    }
    public static implicit operator int(RGB value) {
        return value.Value;
    }
}
Run Code Online (Sandbox Code Playgroud)