2017-03-09 30 views
12

Obecnie szukam przeniesienia mojego metro hash implementon do korzystania z funkcji C# 7, ponieważ kilka części może skorzystać z ref lokalne, aby poprawić wydajność. Hash wykonuje obliczenia na tablicy ulong[4], ale wynikiem jest tablica 16 byte. Obecnie kopiuję tablicę ulong do bufora wyniku byte, ale zajmuje to trochę czasu. Więc zastanawiam się czy System.Runtime.CompilerServices.Unsafe jest bezpieczny w użyciu tutaj:Unsafe.As z tablicy bajtów do tablicy ulong

var result = new byte[16]; 
ulong[] state = Unsafe.As<byte[], ulong[]>(ref result); 
ref var firstState = ref state[0]; 
ref var secondState = ref state[1]; 
ulong thirdState = 0; 
ulong fourthState = 0; 

Powyższy kod urywek oznacza, że ​​używam bufor wynikają także dla części moich obliczeń państwowych, a nie tylko do ostatecznego wyjścia.

Moje testy jednostkowe zakończyły się sukcesem i zgodnie z benchmarkdnetnet pomijanie kopii bloku spowodowałoby wzrost wydajności o jeden stopień, który jest wystarczająco wysoki, aby sprawdzić, czy jest ono poprawne.

+0

Witaj tutaj i dobre pierwsze pytanie! –

+3

To, co robisz, to stara "sztuczka" rzucania przez strukturę (ta jedna http://stackoverflow.com/a/35841815/613130) ... Jeśli zaznaczysz 'stan.Length' zobaczysz, że to jest złe". – xanatos

+2

Wciąż bardzo interesująca biblioteka, którą znalazłeś :-) – xanatos

Odpowiedz

1

C# obsługuje "stałe bufory", tutaj tego rodzaju rzeczy możemy zrobić:

public unsafe struct Bytes 
    { 
     public fixed byte bytes[16]; 
    } 

następnie

public unsafe static Bytes Convert (long[] longs) 
    { 
     fixed (long * longs_ptr = longs) 
       return *((Bytes*)(longs_ptr)); 
    } 

Spróbuj. (Tablice 1D typów pierwotnych w C# są zawsze przechowywane jako ciągły blok pamięci, dlatego przyjmowanie adresu (zarządzanych) tablic jest w porządku).

Można też jeszcze powrócić wskaźnik dla większej prędkości:

public unsafe static Bytes * Convert (long[] longs) 
    { 
     fixed (long * longs_ptr = longs) 
     return ((Bytes*)(longs_ptr)); 
    } 

i manipulować/dostępu do bajtów, jak chcesz.

 var s = Convert(longs); 
     var b = s->bytes[0]; 
Powiązane problemy