2011-02-02 5 views
6

У меня есть следующий массив:Определение количества байтов, используемых переменной

byte[][] A = new byte[256][]; 

Каждый элемент этого массива ссылается на другой массив.

A[n] = new byte[256]; 

Однако большинство элементов ссылаются на один и тот же массив. Фактически, массив A ссылается только на два или три уникальных массива.

Есть ли простой способ определить, сколько памяти использует вся вещь?

ответ

5

Если ваш вопрос, чтобы узнать количество уникальных 1D массивов, вы можете сделать:

A.Distinct().Count() 

Это следует делать, потому что равенство массивов работает на референсной-равенство по умолчанию.

Но, возможно, вы ищете:

A.Distinct().Sum(oneDimArray => oneDimArray.Length) * sizeof(byte) 

Конечно, «количество байтов, используемых переменных» является несколько неточным термином. В частности, приведенное выше выражение не учитывает хранение переменной A, ссылки в массиве с зазубриной, накладные расходы, выравнивание и т. Д.

РЕДАКТИРОВАНИЕ: Как указывает Роб, может потребоваться отфильтровать ссылки null, если jagged-array может содержать их.

Вы можете оценить стоимость хранения ссылок в рваном массиве с (unsafe контекстом):

A.Length * sizeof(IntPtr) 
+0

необходимо также нулевой чек (a.Distinct() Где (аа => аа = нуль) .sum (аа => aa.Length) * SizeOf (байт).!) Dump();. – Rob

+0

@ Rob: Спасибо, отметил. – Ani

+0

Спасибо. (Хороший код, BTW.) Я пишу алгоритм поиска Boyer-Moore и смотрю многоэтапные таблицы, чтобы уменьшить объем памяти, используемый для таблицы сдвига и символов Unicode. Он работает, но я не знаю, сколько памяти я спасу. Поэтому меня также интересуют байты, используемые A в дополнение к массивам, на которые ссылаются. Я думаю, его 4 или 8 байт за элемент (в зависимости от того, 32 или 64-битная сборка). Это не похоже на то, что C# может мне это сказать. –

1

Я не верю, что есть какой-либо встроенное функции.

Быстро взбивал это, не проверял его, однако;

void Main() 
{ 
    byte[][] a = new byte[256][]; 
    var someArr = new byte[256]; 
    a[0] = someArr; 
    a[1] = someArr; 
    a[2] = new byte[256]; 
    getSize(a).Dump(); 
} 

private long getSize(byte[][] arr) 
{ 
    var hashSet = new HashSet<byte[]>(); 
    var size = 0; 
    foreach(var innerArray in arr) 
    { 
     if(innerArray != null) 
      hashSet.Add(innerArray); 
    } 

    foreach (var array in hashSet) 
    { 
     size += array.Length * sizeof(byte); 
    } 
    return size; 
} 
1

Я просто модифицированный метод getSize для использования класса помощника буфера.

private long getSize(byte[][] arr) 
{ 
    Dictionary<byte[], bool> lookup = new Dictionary<byte[], bool>(); 

    long size = 0; 

    foreach (byte[] innerArray in arr) 
    { 
     if (innerArray == null || lookup.ContainsKey(innerArray)) continue; 
     lookup.Add(innerArray, true); 
     size += Buffer.ByteLength(innerArray); 
    } 

    return size; 
} 
+0

Я получаю сообщение об ошибке «Объект должен быть массивом примитивов.» При вызове ByteLength(). –

+0

@ Jonathan Wood, innerArray - это массив байтов, а байт - примитивный тип. Вы проходите мимо? или вы используете другой тип, кроме байта? –

+0

Да, ты прав. Он работает только с массивом простых байтов []. Для байт [256] он возвращает (неожиданность) 256. –

Смежные вопросы