为了避免发明热水,我在这里问......
我有一个包含大量数组的应用程序,而且内存不足。
所以我的想法是将List<int>
压缩到其他东西,这将具有相同的接口(例如IList<T>
),但我可以使用更短的整数代替int
。
例如,如果我的值范围是0 - 100.000.000,我只需要ln2(1000000)= 20位。因此,不是存储32位,而是可以减少多余的内存并将内存需求降低12/32 = 37.5%。
你知道这种数组的实现吗? c ++和java也可以,因为我可以很容易地将它们转换为c#。
附加要求(因为每个人都开始让我理解这个想法):
编辑:
请不要告诉我不要这样做。对此的要求经过深思熟虑,并且它是唯一的选择。
此外,1M的值范围和20位仅为示例。我的案例具有所有不同的范围和整数大小。
另外,我甚至可以有更短的整数,例如7位整数,然后打包
00000001
11111122
22222333
33334444
444.....
表示前4个元素,打包成5个字节。
几乎完成编码 - 将很快发布......
答案 0 :(得分:3)
由于你只能在字节量子中分配内存,所以你实际上是在询问是否/如何使用3个字节而不是4个字符来拟合整数(但请参见下面的#3)。这不是一个好主意。
您可能希望尝试以下方式:
答案 1 :(得分:1)
从32位到24位的一个选项是创建一个存储3字节内的整数的自定义结构:
public struct Entry {
byte b1; // low
byte b2; // middle
byte b3; // high
public void Set(int x) {
b1 = (byte)x;
b2 = (byte)(x >> 8);
b3 = (byte)(x >> 16);
}
public int Get() {
return (b3 << 16) | (b2 << 8) | b1;
}
}
然后,您只需创建List<Entry>
。
var list = new List<Entry>();
var e = new Entry();
e.Set(12312);
list.Add(e);
Console.WriteLine(list[0].Get()); // outputs 12312
答案 2 :(得分:1)
这让我想起了base64和类似的binary-to-text encoding。 它们占用8位字节,然后进行一些bit-fiddling将它们打包成4位,5位或6位可打印字符。 这也让我想起了Zork标准信息交换代码(ZSCII),它将3个字母打包成2个字节,每个字母占5位。 听起来你想要取一堆10位或20位整数并将它们打包成8位字节的缓冲区。
源代码可用于处理单个位的打包数组的许多库 (a b c d e)。
也许你可以 (a)下载该源代码并修改源代码(从某些BitArray或其他打包编码开始),重新编译以创建一个新的库来处理打包和解包10位或20位整数而不是单个位。 它可能需要更少的编程和测试时间 (b)编写一个库,从外部看起来像(a)一样,但在内部它将20位整数分成20个独立的位,然后使用(未修改的)BitArray类存储它们。
答案 3 :(得分:0)
编辑:鉴于您的整数是唯一的,您可以执行以下操作:存储唯一的整数,直到您存储的整数数量是最大数量的一半。然后切换到存储您没有的整数。这将使存储空间减少50%。
在尝试使用20位整数之前,可能值得探索其他简化技术。
如何处理重复的整数?如果有大量重复项,则可以通过将整数存储在Dictionary<int, int>
中来减少存储大小,其中键是唯一的整数,值是相应的计数。请注意,这假设您不关心整数的顺序。
你的整数是否都是唯一的?也许你在0到100 mil的范围内存储了很多独特的整数。在这种情况下,您可以尝试存储您没有的整数。然后在确定您是否有整数i
时,只询问它是否在您的收藏中。