2012-07-07 26 views
2

我试图做的事:如何在一个值中构建变量1到4字节的结构?

我想在RAM中存储非常多的数据。为了更快地存取和更少的内存占用我需要使用结构值的数组:

MyStruct[] myStructArray = new MyStruct[10000000000]; 

现在我想要存储的无符号整型值与MYSTRUCT一个,两个,三个或四个字节。但它应该只使用尽可能少的内存量。当我将一个值存储一个字节时,它应该只使用一个字节,依此类推。

我可以通过类来实现这个,但这不合适,因为指向该对象的指针在64位系统上需要8个字节。所以最好为每个数组条目存储4个字节。但是我想在需要时只存储/使用一个/两个/三个字节。所以我不能使用一些奇特的课程。

我也不能使用一个数组与一个字节,一个数组与两个字节等,因为我需要的值的特殊顺序。而且这些值非常混杂,因此在切换到另一个阵列时存储额外的参考将无济于事。

有没有可能想要什么或者是否只是存储一个4字节的数组的唯一方法,无论我只需要存储一个字节,两个字节约60%的时间和三个字节约25%时间?

+1

你看着[StructLayoutAttribute(http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.aspx)? – Oded 2012-07-07 21:47:48

+0

这对我的情况没有帮助。我需要在一个结构中包含一个字节值,两个字节值,三个字节值和四个字节值的结构。但是,当我仅存储一个字节时,仅使用一个字节。我不知道StructLayoutAttribute如何提供帮助。 – Chris 2012-07-07 21:51:18

+0

哪个是您的主要目标,内存使用率较低还是访问速度较快? – Dave 2012-07-07 21:52:08

回答

2

如果您愿意牺牲一些额外的CPU时间并浪费每个存储值的额外2位或4位,那么您可以接近此要求。

您可以使用字节byte[]并将其与BitArray collection结合使用。在byte []中,您只需按顺序存储一个,两个,三个或四个字节,并且在BitArray中以二进制形式表示(一对两位),或者将一个位置1以表示一组新的字节或结束,但是你实现它)在你的数据数组中。

但是你可以得到这样的记忆:

byte[] --> [byte][byte][byte][byte][byte][byte][byte]... 
BitArray --> 1001101... 

这意味着你有3个字节,1个字节,2个字节等存储在您的字节数组值。

或者你也可以交替编码您bitarray二进制对使它更小。这意味着你可以在你的实际数据字节中尝试1.0625到1.25字节之间的空间。

这取决于你的实际数据(你MyStruct)如果这就够了。如果您需要区分结构中哪些字节真正对应的值,则可以浪费BitArray中的一些额外位。

更新到你的O(1)要求:

使用另一种索引结构,这将存储一个指数每N个元素,例如1000。然后你可以用指数234241例如接入项目为

indexStore[234241/1000] 

,让你元素234000的指数,那么你只需要通过检查BitArray那些几百元计算元素234241确切的指标。

O(常量)被acheieved这样,常量可以与主要指数的密度来控制的,当然你交易时间换空间。

6

这是不可能的。 CLR如何处理以下表达式?

myStructArray[100000] 

如果元素大小可变,CLR无法知道第100000个元素的地址。因此数组元素的大小始终是固定的。

如果您不需要O(1)访问,可以实现在byte[]的顶部可变长度元素和自己搜索阵列。

您可以将列表拆分为1000个子列表,它们是单独打包的。这样你平均可以获得O(n/2000)的搜索性能。也许这在实践中已经够好了。

“打包”数组平均只能在O(n/2)中搜索。但是,如果您的部分数组的大小是1/1000的大小,它将变成O(n/2000)。您可以选取O(1)中的部分数组,因为它们全部大小相同。

此外,您可以调整部分数组的数量,使它们单独大小约为1k个元素。那时,数组对象的开销和对它的引用就消失了。这会给你O(1000/2 + 1)查找性能,我认为是比O(n/2)相当改进。这是一个恒定查询(具有很大的常量)。

+0

这就是我的问题。我现在想着用byte []自己构建我的数组。我会用一个字节的第一位来判断是否有第二个字节,等等。但目前我需要O(1)访问。循环遍历整个阵列会给我带来O(n/2)的访问时间,我认为。 – Chris 2012-07-07 22:35:12

+0

这是真实的,我相信这是不可能有在这种情况下时间和空间效率。您可以将列表拆分为1000个子列表,这些子列表单独打包。这样你平均可以获得O(n/2000)的性能。够了吗? – usr 2012-07-07 22:45:22

+0

目前我不能说,因为我不认为这将是O(N/2000)。当我拥有100亿个物品时,将它们打包成1000个阵列,每个子列表剩下1000万个物品。现在每个条目都有一个可变长度。我认为现在重要的部分是“自己搜索阵列”部分。你有没有其他的/更好的建议比我会这样做(使用第一位来表明还有一个字节等)? – Chris 2012-07-07 23:03:48

1

你不能这样做。

如果数据未排序,并没有什么更多的,你能说一下,那么你不会是能够做到你想要什么。

简单的场景:

array[3] 

应指向一些内存地址。但是,您如何知道array[0] - array[2]的尺寸?要以O(1)方式存储这些信息,您只会浪费比您想要首先保存的更多内存。

你在开箱思考,这很好。但是,我的猜测是,这是你试图摆脱的错误框。如果您的数据真的是随机的,并且您希望直接访问每个数组成员,则必须使用每个数字所需的MAXIMUM宽度。抱歉。

我有一个类似的情况,与具有长度比我需要存储32位的更小的号码。但他们都是固定的宽度,所以我能够通过定制容器和一些位移来解决这个问题。

HOPE:

http://www.dcc.uchile.cl/~gnavarro/ps/spire09.3.pdf

也许你能理解它,然后你就可以不仅有8,16,24,每个号码32位,但任何数量的大小...

0

我几乎开始寻找一些像PkZip程序一样的短字编码变体。

甚至RLE编码。

或者试着去了解你的数据的使用更好。等,如果这些是所有矢量或东西,然后有被禁止等,-1,-1某些组合,-1是基本上无意义的一个金融绘图应用,因为它表示数据外侧在graphable范围。如果你可以发现你的数据有些古怪,你可以通过为不同的需求设置不同的结构来缩小规模。

相关问题