需要4 GB或5 GB数字的算法 - 是否可能?

Tek*_*ept 4 c# memory biginteger

好的,这个问题确实是一个挑战!

背景

我正在研究一个涉及大于正常数字的基于算术的项目.我是新的,我将使用4 GB封装文件大小的最坏情况 - (我正在跳跃甚至将其扩展到5GB上限,因为我之前看到的文件大小超过4 GB - 特别是图像*. iso文件)

一般问题

现在,我将应用计算的算法此刻无关紧要,但是加载和处理如此大量的数据 - 数字 - 这样做.

  • A System.IO.File.ReadAllBytes(String)只能读取2 GB的文件数据上限,所以这是我的第一个问题 - 如何加载和/或配置访问内存,这样的文件大小 - 两倍,如果不是更多?
  • 接下来,我正在编写自己的类来将'stream'或字节数组视为一个大数字,并添加多个运算符方法来执行十六进制算法,直到我System.Numerics.BigInteger()在线阅读该类 - 但是因为没有BigInteger.MaxValue,我只能一次加载最多2 GB的数据,我不知道它的潜力是什么BigInteger- 甚至与我写的对象Number()(具有我想要的最小潜力)相比.可用内存和性能也存在问题,但我并不关心速度,而是成功地完成了这个实验过程.

摘要

  • 我该如何加载4-5千兆字节的数据?
  • 加载后如何存储和处理数据?坚持BigInteger或完成我自己的Number课程?
  • 如何在运行时处理如此大量的内存而不会耗尽内存?我将像任何其他数字一样处理4-5 GB的数据而不是字节数组 - 执行除法和乘法等算法.

PS根据非披露协议,我无法透露有关该项目的太多信息.;)

对于那些希望从我的Number对象中看到每个字节数组加法器(C#)的示例运算符的人:

public static Number operator +(Number n1, Number n2)
{
    // GB5_ARRAY is a cap constant for 5 GB - 5368709120L
    byte[] data = new byte[GB5_ARRAY];
    byte rem = 0x00, bA, bB, rm, dt;
    // Iterate through all bytes until the second to last
    // The last byte is the remainder if any
    // I tested this algorithm on smaller arrays provided by the `BitConverter` class,
    // then I made a few tweeks to satisfy the larger arrays and the Number object
    for (long iDx = 0; iDx <= GB5_ARRAY-1; iDx++)
    {
        // bData is a byte[] with GB5_ARRAY number of bytes
        // Perform a check - solves for unequal (or jagged) arrays
        if (iDx < GB5_ARRAY - 1) { bA = n1.bData[iDx]; bB = n2.bData[iDx]; } else { bA = 0x00; bB = 0x00; }
        Add(bA, bB, rem, out dt, out rm);
        // set data and prepare for the next interval
        rem = rm; data[iDx] = dt;
    }
    return new Number(data);
}
private static void Add(byte a, byte b, byte r, out byte result, out byte remainder)
{
    int i = a + b + r;
    result = (byte)(i % 256); // find the byte amount through modulus arithmetic
    remainder = (byte)((i - result) / 256); // find remainder
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 6

通常情况下,你会过程中使用流API的大文件,无论是原始二进制(Stream),或者通过某种协议读取器(XmlReader,StreamReader,等).在某些情况下,这也可以通过内存映射文件来完成.这里的关键点是,您一次只能查看文件的一小部分(中等大小的数据缓冲区,逻辑"行"或"节点"等 - 具体取决于方案).

这有点奇怪的是你想要以某种方式直接映射到某种形式的大数字.坦率地说,我不知道在没有更多信息的情况下我们如何能够提供帮助,但是如果你正在处理这个大小的实际数量,我认为除非二进制协议使方便,否则你将会挣扎.并且"执行诸如除法和乘法之类的算术"对于原始数据是没有意义的; 只有定义了自定义操作的解析数据才有意义.

另外:请注意,在.NET 4.5中,您可以翻转配置开关以扩展阵列的最大大小,超过2GB限制.它仍然一个限制,但是:它有点大.不幸的是,元素的最大数量仍然是相同的,所以如果你使用byte[]数组它将无济于事.但是如果你正在使用SomeCompositeStruct[]你应该能够获得更高的使用率.请参阅gcAllowVeryLargeObjects