2011-02-02 22 views
6

że ma następujący układ:Określanie liczby bajtów używanych przez zmienną

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

Każdy element tej tablicy odwołuje kolejną tablicę.

A[n] = new byte[256]; 

Jednak większość elementów odnosi się do tej samej tablicy. W rzeczywistości tablica A odwołuje się tylko do dwóch lub trzech unikatowych tablic.

Czy istnieje prosty sposób określenia, ile pamięci wykorzystuje całe urządzenie?

Odpowiedz

5

Jeśli pytanie jest dowiedzieć się liczbę unikalnych 1D tablic, można zrobić:

A.Distinct().Count() 

Należy to zrobić, ponieważ równość tablic działa na referencyjnym-równości domyślnie.

Ale może szukasz:

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

Oczywiście, „liczba bajtów używanych przez zmienne” jest nieco nieprecyzyjne określenie. W szczególności powyższe wyrażenie nie obejmuje przechowywania zmiennej A, odniesień w poszarpanej tablicy, narzutu, wyrównania itp.

EDYCJA: Jak zaznacza Rob, może być konieczne przefiltrowanie null referencji, jeśli Jagged-tablica może je zawierać.

Można oszacować koszt przechowywania odniesienia w postrzępionych array (unsafe z kontekstu):

A.Length * sizeof(IntPtr) 
+0

Należy również null Sprawdź (a.Distinct() Gdzie (aa => aa = null) .Sum (aa => aa.Length) * sizeof (bajtów).!) Dump(). – Rob

+0

@Rob: Dzięki, zauważył. – Ani

+0

Dzięki. (Ładny kod, BTW.) Piszę algorytm przeszukiwania Boyera-Moore'a i przyglądam się wielostopniowym tabelom, aby zmniejszyć ilość pamięci używanej do tabeli zmian i znaków Unicode. Działa, ale nie wiem, ile pamięci oszczędzam. Tak więc interesują mnie również bajty używane przez A oprócz przywoływanych tablic. Przypuszczam, że jest to 4 lub 8 bajtów na element (w zależności od tego, czy kompilacja jest 32 czy 64-bitowa). Wygląda na to, że C# nie może mi tego powiedzieć. –

1

nie wierzę tam ewentualne wbudowane funkcjonalności.

Zrobiłem to bardzo szybko, jednak nie testowałem tego jednak;

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

Właśnie zmodyfikowałem metodę getSize Rob'a, aby używać klasy pomocnika bufora.

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

Pojawia się błąd "Obiekt musi być tablicą prymitywów." Na wywołanie ByteLength(). –

+0

@ Jonathan Wood, innerArray jest tablicą bajtów, a bajt jest typem pierwotnym. Czy przechodzisz w arr? lub używasz innego typu niż bajt? –

+0

Tak, masz rację. Działa z prostą tablicą bajtów []. Dla bajtu [256] zwraca (niespodzianka) 256. –

Powiązane problemy