2013-03-09 20 views
5

C# .Net (3.5 ve üstü) 'de, işlemde bir çöp üretmeden bir değişkeni bir bayt [] arabelleğine kopyalamak mümkün mü? ÖrneğinC# Değişkenler çöp oluşturmadan arabelleğe kopyalansın mı?

: bitsel operatörleri kullanarak eğer

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)); 

... 

çöp (a ref varsayarsak artık buna tutulur) olur byte [] bayt aracı nesne oluşturur ...

acaba değişken ara bellek [] oluşturmadan doğrudan arabelleğe kopyalanabilir?

+0

Evet, bu mümkün, ama bana erken gibi optimize ediyor gibi geliyor. Küçük bayt dizileri ve benzerleri gibi bir yöntem çağrısında oluşturduğunuz çöpün tümü Gen 0 nesnesidir ve büyük olasılıkla birkaç milisaniye veya muhtemelen daha az toplanır. CLR'de geçici nesne tahsisi ve koleksiyonu son derece verimlidir. – codekaizen

+0

Whare Gen 0 nesnesidir? – markmnl

+0

(Endişeniz için - Optimizasyonun zamansız olduğunu düşünmüyorum - Ben böyle kulağa nasıl geldiğimi bilmiyorum - Telefonların kullanacağı ve arabelleği 100'ün muhtemelen binlerce kez bir secound kullanan bir kütüphane yazıyorum - ve GC, bu tür kaynak kısıtlı cihazlarla ilgili bir endişe kaynağıdır). – markmnl

cevap

2

Kullanım işaretçileri iyi ve en hızlı yoludur: yapabilirsiniz Bunu herhangi bir değişken sayısı ile yapın, boşa harcanan bellek yok, sabit deyimin biraz yükü var ancak çok küçük

 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

Belki de söylenecek bir şey: tüm sabitlenmiş (sabit) nesnelere dikkat et. Sonunda daha fazla bellek kullanarak sonuçlanabilecek yığın parçalanmasına neden olabilirler. – Caramiriel

1

Neden sadece yapamaz:

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

Not dizisi burada orijinal ınt32 için depoya bir indirection değil olduğunu, bu çok bir kopyasıdır.

Sen örnekte bytes eşdeğer olduğunu belki endişeli:

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

.. ama olmadığını seni temin ederim; Bu, Int32 kaynağındaki baytların bayt kopyası tarafından bir bayttır.

DÜZENLEME: Düzenlemenize dayanarak

, ben (güvensiz bağlamı gerektirir) böyle bir şey istiyorum düşünüyorum:

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

Örneklerimden farklı olarak, arabamın çok sayıda değişken tutması gerekiyor - benim sorumu güncelleyeceğim – markmnl

İlgili konular