16

私たちのアプリケーションでは、非常に大きなバイト配列があり、これらのバイトを異なる型に変換する必要があります。現在、BitConverter.ToXXXX()この目的で使用しています。私たちのヘビーヒッターは、ToInt16ToUInt64.

の場合UInt64、問題は、データ ストリームが実際には大きな整数を表す 6 バイトのデータを持っていることです。6 バイトのデータを に変換するネイティブ関数がないため、次のUInt64ようにします。

UInt64 value = BitConverter.ToUInt64() & 0x0000ffffffffffff;

の使用ToInt16はより簡単で、ビット操作を行う必要はありません。

私たちはこれら 2 つの操作を非常に多く行っているため、SO コミュニティにこれらの変換を行うためのより高速な方法があるかどうかを尋ねたいと思いました。現在、全 CPU サイクルの約 20% がこれら 2 つの関数によって消費されています。

4

4 に答える 4

8

メモリ ポインタを直接使用することを考えたことはありますか。そのパフォーマンスを保証することはできませんが、C++\C では一般的なトリックです...

        byte[] arr = { 1, 2, 3, 4, 5, 6, 7, 8 ,9,10,11,12,13,14,15,16};

        fixed (byte* a2rr = &arr[0])
        {

            UInt64* uint64ptr = (UInt64*) a2rr;
            Console.WriteLine("The value is {0:X2}", (*uint64ptr & 0x0000FFFFFFFFFFFF));
            uint64ptr = (UInt64*) ((byte*) uint64ptr+6);
            Console.WriteLine("The value is {0:X2}", (*uint64ptr & 0x0000FFFFFFFFFFFF));
        }

ビルド設定でアセンブリを「安全でない」ものにし、これを行うメソッドも安全でないことをマークする必要があります。このアプローチでは、リトルエンディアンにも縛られています。

于 2011-02-07T19:15:59.773 に答える
5

このクラスを使用して、高速な「ブロック コピー」操作System.Bufferとして、配列全体を別の型の別の配列にコピーできます。

BlockCopy メソッドは、メモリへのオフセットを使用して src パラメータ配列内のバイトにアクセスします。インデックスや配列の上限と下限などのプログラミング構造は使用しません。

配列型は「プリミティブ」型である必要があり、整列する必要があり、コピー操作はエンディアンに依存します。6 バイトの整数の場合、6 バイトごとに 2 バイトのパディングでソース配列を取得できない限り、.NET の「プリミティブ」型のいずれとも整列できませんInt64。ただし、この方法は の配列に対して機能するためInt16、一部の操作が高速化される場合があります。

于 2011-02-07T20:21:52.420 に答える
2

なぜだめですか:

UInt16 valLow = BitConverter.ToUInt16();
UInt64 valHigh = (UInt64)BitConverter.ToUInt32();
UInt64 Value = (valHigh << 16) | valLow;

これを単一のステートメントにすることもできますが、おそらく JIT コンパイラーが自動的にそれを行います。

これにより、最終的に捨ててしまう余分な 2 バイトを読み取ることができなくなります。

それでも CPU が減らない場合は、バッファーからバイトを直接読み取る独自のコンバーターを作成することをお勧めします。配列のインデックスを使用するか、必要に応じてポインターを使用した安全でないコードを使用できます。

コメンターが指摘したように、これらの提案のいずれかを使用する場合、特定の「エンディアンネス」に制限されるか、コードを記述してリトル/ビッグエンディアンを検出し、それに応じて対応する必要があることに注意してください. 上記のコード サンプルは、リトル エンディアン (x86) で動作します。

于 2011-02-07T16:55:17.427 に答える
1

ここで同様の質問については私の答えを参照してください。これは、ジミーの答えと同じ安全でないメモリ操作ですが、消費者にとってより「友好的な」方法です。byte配列を配列として表示できるようになりますUInt64

于 2012-05-10T03:59:26.270 に答える