Как получить огромный список? Больше 2 ГиБ? - PullRequest
2 голосов
/ 10 октября 2011

В .Net framework 2 ГиБ - это максимальный объем памяти, который вы можете выделить для объекта.Этот факт независим от платформы ( x64 или x86 или ...).Мне нужно иметь огромный список с более чем 2 ^ 30 комплексными числами (каждое по 16 байт).

Примечание:

Как и в 32-битных операционных системах Windows,это ограничение в 2 ГБ на размер объекта, который можно создать при запуске 64-разрядного управляемого приложения в 64-разрядной операционной системе Windows.

из http://msdn.microsoft.com/en-us/library/ms241064%28VS.80%29.aspx

Ответы [ 4 ]

2 голосов
/ 10 октября 2011

Сделайте это зазубренным вместо;Complex[][] например.При необходимости он может быть широко прямоугольным зазубренным, просто всегда используя один и тот же размер для внутренних массивов.использовать связанный список больших списков;преимущество в том, что его легче расширять.

2 голосов
/ 10 октября 2011

Затем вам нужно будет инкапсулировать это другим способом - создайте свою собственную коллекцию, которая может обрабатывать достаточное количество данных и, вероятно, будет использовать long вместо int для значений индекса и т. Д. , делегируя меньшие коллекции внутренне. Я подозреваю, что это не будет очень весело, но я не вижу, что у вас есть много других вариантов.

По сути, все, что поддерживается одним массивом, может столкнуться с проблемами.

1 голос
/ 10 октября 2011

В .NET 4.5 создается впечатление, что массивы на самом деле могут быть больше 2 ГБ. С жестким ограничением на количество элементов, а не на размер. http://msdn.microsoft.com/en-us/library/hh285054(v=vs.110).aspx

Рассказывает о новом флаге и новых ограничениях на массивы.

1 голос
/ 10 октября 2011

Я бы реализовал класс-оболочку, который использует несколько внутренних массивов.

Аналогично следующему:

void Main()
{
    long count=3*1024*1024;
    var arr=new LargeArray<Complex>(count,12);
    for(long i=0;i<count;i++)
    {
      arr[i]=new Complex(i,-i);
    }
    for(long i=0;i<count;i++)
    {
      if(arr[i].R!=i)
        throw new Exception("Fail"+i+" "+arr[i].R);
    }
}

struct Complex
{
  public double R,I;

  public Complex(double r,double i)
    {
      R=r;
      I=i;
    }
}


class LargeArray<T>
{
  private readonly int partBits;  
  private readonly long size;

  private T[][] data;

  public T this[long index]
  {
    get
    {
      if((ulong)index>=(ulong)size)
        throw new IndexOutOfRangeException();
      int part=(int)(index>>partBits);
      int subIndex=(int)(index&((1<<partBits)-1));
      return data[part][subIndex];
    }
    set
    {
      if((ulong)index>=(ulong)size)
        throw new ArgumentOutOfRangeException();
      int part=(int)(index>>partBits);
      int subIndex=((int)index&((1<<partBits)-1));
      data[part][subIndex]=value;
    }
  }

  public LargeArray(long size,int partBits)
  {
    this.size=size;
    this.partBits=partBits;
    int partSize=1<<partBits;
    int partCount=(int)(((size-1)>>partBits)+1);
    data=new T[partCount][];
    for(int i=0;i<partCount;i++)
      data[i]=new T[partSize];
  }
}

Если вы используете 64-битный процесс, это работает за пределами 2 ГБ.Я попробовал его с 5 ГБ, и, кроме того, что мой комп остановился, он работал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...