2017-03-09 10 views
12

私は現在、metro hash implementonをC#7の機能を使用するように移植しています。 ハッシュはulong[4]配列の計算を行いますが、結果は16 byteの配列になります。現在、ulongの配列を結果のbyteバッファにコピーしていますが、これには少し時間がかかります。 System.Runtime.CompilerServices.Unsafeここで使用しても安全である場合 はので、私は思ったんだけど:バイト配列から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によると、ブロックコピーをスキップすると、が20%のパフォーマンスが向上します。これは、それが正しいかどうかを調べるのに十分です。

+0

ようこそ、最初の質問! –

+3

あなたがやっていることは、struct(これは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]; 
関連する問題