2017-03-09 43 views
12

我目前正在考慮移植我的metro hash implementon以使用C#7功能,因爲幾個部分可能從ref當地人獲益以提高性能。 散列在ulong[4]數組上進行計算,但結果是16 byte數組。目前我正在將ulong數組複製到結果byte緩衝區,但這需要一些時間。 所以我想知道如果System.Runtime.CompilerServices.Unsafe是安全的,在這裏使用:Unsafe.As從字節數組到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; 

上面的代碼片斷意味着我使用的結果緩衝區也爲我州的計算部分,而不是隻對最終輸出。

我的單元測試是成功的,根據benchmarkdotnet跳過塊複製會導致性能增加,這足以讓我發現它是否正確使用它。

+0

歡迎來到這裏和第一個問題! –

+3

你在做什麼是通過一個結構(這一個http://stackoverflow.com/a/35841815/613130)鑄造的舊「訣竅」...如果你檢查'state.Length'你會看到這是錯誤的」。 – xanatos

+2

仍然非常有趣的圖書館,你已經找到:-) – xanatos

回答

1

C#支持 「固定緩衝存儲器」,這裏的那種東西,我們可以這樣做:

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

然後

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

試試吧。 (C#中原始類型的1D數組總是作爲連續的內存塊存儲,這就是爲什麼獲取(託管)數組的地址很好)。

你也可以甚至返回指針更快的速度:

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

和操作/只要你想訪問的字節數。

 var s = Convert(longs); 
     var b = s->bytes[0];