2013-03-09 7 views
5

jest to możliwe, C# NET (3,5 i powyżej), aby skopiować zmienną w [] buforze bajtów bez tworzenia śmieci w procesie?C# Kopiowanie zmiennych do bufora bez tworzenia śmieci?

Na przykład:

int variableToCopy = 9861; 

byte[] buffer = new byte[1024]; 
byte[] bytes = BitConverter.GetBytes(variableToCopy); 
Buffer.BlockCopy(bytes, 0, buffer, 0, 4); 

float anotherVariableToCopy = 6743897.6377f; 
bytes = BitConverter.GetBytes(anotherVariableToCopy); 
Buffer.BlockCopy(bytes, 0, buffer, 4, sizeof(float)); 

... 

tworzy byte [] bajtów pośrednika przedmiot, który staje się śmieci (zakładając ref nie jest już utrzymywane do niego) ...

Zastanawiam się, czy za pomocą tych operatorów bitowe zmienna może być skopiowana bezpośrednio do bufora bez tworzenia bajta pośredniego []?

+0

Tak, jest to możliwe, ale brzmi to tak, jak przedwcześnie optymalizujesz. Śmieci, które tworzysz w wywołaniu metody, podobnie jak tablice o małych bajtach i tym podobne, są obiektami klasy 0 i będą zbierane prawdopodobnie w ciągu kilku milisekund lub prawdopodobnie nawet mniej. Efemeryczny przydział i gromadzenie obiektów w CLR jest niezwykle wydajny. – codekaizen

+0

Co to są obiekty typu 0? – markmnl

+0

(Dla Twojej uwagi - nie sądzę, że optymalizacja jest przedwczesna - nie jestem pewien, jak to brzmiałem - piszę bibliotekę, która będzie używana przez telefony i używająca bufora 100 prawdopodobnie tysiące razy na sekundę - i GC jest problemem związanym z urządzeniami o ograniczonych zasobach). – markmnl

Odpowiedz

2

użyć wskaźników jest najlepszym i najszybszym sposobem: Można zrobić to z dowolną liczbą zmiennych, nie ma zmarnowanej pamięci, stała instrukcja ma trochę narzut, ale jest za mała

 int v1 = 123; 
     float v2 = 253F; 
     byte[] buffer = new byte[1024]; 
     fixed (byte* pbuffer = buffer) 
     { 
      //v1 is stored on the first 4 bytes of the buffer: 
      byte* scan = pbuffer; 
      *(int*)(scan) = v1; 
      scan += 4; //4 bytes per int 

      //v2 is stored on the second 4 bytes of the buffer: 
      *(float*)(scan) = v2; 
      scan += 4; //4 bytes per float 
     } 
+0

Może warto wspomnieć: zajmij się wszystkimi przypiętymi (stałymi) obiektami. Mogą powodować fragmentację sterty, która może skończyć się użyciem większej ilości pamięci w końcu. – Caramiriel

1

Dlaczego nie można po prostu zrobić:

byte[] buffer = BitConverter.GetBytes(variableToCopy); 

Zauważ, że tablica jest tutaj nie wskazanie pośrednie do przechowywania oryginalnego Int32, jest bardzo dużo kopia.

Jesteś być może obawiają się, że bytes w przykładzie jest równoważna:

unsafe 
{ 
    byte* bytes = (byte*) &variableToCopy; 
} 

.. ale zapewniam cię, że nie jest; jest to bajt po bajtowej kopii bajtów w źródłowym Int32.

EDIT:

oparciu o edycję, myślę, że chcesz coś takiego (wymaga niebezpiecznego kontekstu):

public unsafe static void CopyBytes(int value, byte[] destination, int offset) 
{ 
    if (destination == null) 
     throw new ArgumentNullException("destination"); 

    if (offset < 0 || (offset + sizeof(int) > destination.Length)) 
     throw new ArgumentOutOfRangeException("offset"); 

    fixed (byte* ptrToStart = destination) 
    { 
     *(int*)(ptrToStart + offset) = value; 
    } 
} 
+0

ponieważ w przeciwieństwie do mojego przykładu mój bufor musi zawierać wiele zmiennych - zaktualizuję moje pytanie – markmnl

Powiązane problemy