如何使用结构有效地保存包含内存中许多位字段的表?

时间:2017-07-19 10:07:19

标签: vb.net data-structures

在VB.Net中,在内存中保存一个由位字段组成的结构的正确方法是什么,这种结构不能完全对齐整个字节,并且至少可以通过两种方式解释,具体取决于具体的位。我只是定义常量并在他们的帮助下提取字段,还是构建结构?

表中的输入实际上只是比特流的32个字节。它的内容在结构中不会改变一次。

访问应该是字段名称,所以我假设某种结构是可行的,包括动态位操作?时间效率就是最重要的。

这是有问题的表格(如果感兴趣,它是MP3框架的附带信息):enter image description here

位置和长度以位为单位,而不是字节。

1 个答案:

答案 0 :(得分:1)

正如评论中所提到的,如果速度是你最关心的问题,那么我会说你想要把所有东西放在堆栈上,或者至少在一个连续的数组中,所以这只需要使用值类型。话虽如此,如果没有对您的实际代码和实际数据进行彻底的性能测试,就无法肯定地说出来。要避免在堆上进行分配,您需要将类型创建为Structure而不是Class。您还希望将字段限制为仅限值类型。由于数组是引用类型,因此您需要将所有256位存储在某些其他类型的字段中。然后,您可以提供解释该原始数据的公共只读属性,并以更有用的格式显示该属性。

最明显的解决方案是使用BigInteger,因为它是一个值类型,可以在单个字段中存储任何大小的整数(在本例中为256位)。然而不幸的是,这没有帮助。即使BigInteger是值类型,它也支持以位为单位的可变长度,因此它将其值存储在数组内部。因此,即使BigInteger是值类型,它仍然将它存储在堆上。其次,即使不是这种情况,它也只支持通过字节数组或一系列数学运算加载其值,一次一个字节。在任何一种情况下,这都会否定使用它的任何好处。另一种方法是创建一组固定值类型的字段,例如Byte

Public Structure SideInfo
    Public Sub New(input As Stream)
        ' Improve this to handle end-of-stream if necessary
        _b1 = CByte(input.ReadByte())
        _b2 = CByte(input.ReadByte())
        _b3 = CByte(input.ReadByte())
        _b4 = CByte(input.ReadByte())
        _b5 = CByte(input.ReadByte())
        _b6 = CByte(input.ReadByte())
        _b7 = CByte(input.ReadByte())
        _b8 = CByte(input.ReadByte())
        _b9 = CByte(input.ReadByte())
        _b10 = CByte(input.ReadByte())
        _b11 = CByte(input.ReadByte())
        _b12 = CByte(input.ReadByte())
        _b13 = CByte(input.ReadByte())
        _b14 = CByte(input.ReadByte())
        _b15 = CByte(input.ReadByte())
        _b16 = CByte(input.ReadByte())
        _b17 = CByte(input.ReadByte())
        _b18 = CByte(input.ReadByte())
        _b19 = CByte(input.ReadByte())
        _b20 = CByte(input.ReadByte())
        _b21 = CByte(input.ReadByte())
        _b22 = CByte(input.ReadByte())
        _b23 = CByte(input.ReadByte())
        _b24 = CByte(input.ReadByte())
        _b25 = CByte(input.ReadByte())
        _b26 = CByte(input.ReadByte())
        _b27 = CByte(input.ReadByte())
        _b28 = CByte(input.ReadByte())
        _b29 = CByte(input.ReadByte())
        _b30 = CByte(input.ReadByte())
        _b31 = CByte(input.ReadByte())
        _b32 = CByte(input.ReadByte())
    End Sub

    Private _b1 As Byte
    Private _b2 As Byte
    Private _b3 As Byte
    Private _b4 As Byte
    Private _b5 As Byte
    Private _b6 As Byte
    Private _b7 As Byte
    Private _b8 As Byte
    Private _b9 As Byte
    Private _b10 As Byte
    Private _b11 As Byte
    Private _b12 As Byte
    Private _b13 As Byte
    Private _b14 As Byte
    Private _b15 As Byte
    Private _b16 As Byte
    Private _b17 As Byte
    Private _b18 As Byte
    Private _b19 As Byte
    Private _b20 As Byte
    Private _b21 As Byte
    Private _b22 As Byte
    Private _b23 As Byte
    Private _b24 As Byte
    Private _b25 As Byte
    Private _b26 As Byte
    Private _b27 As Byte
    Private _b28 As Byte
    Private _b29 As Byte
    Private _b30 As Byte
    Private _b31 As Byte
    Private _b32 As Byte

    Private Const _scfsiMaskB2 As Byte = &HF
    Private Const _scfsiMaskB3 As Byte = &HF0

    Public ReadOnly Property Scfsi As Integer
        Get
            Return (CInt(_b2 And _scfsiMaskB2) << 4) Or (CInt((_b3 And _scfsiMaskB3)) >> 4)
        End Get
    End Property

    ' More read-only properties...

End Structure