C#での最速UINT32からINT変換への最速
-
14-10-2019 - |
質問
値を計算し、UINT32を返す高速ビットレベルのルーチンがあります。この値は、32ビットINTフィールドにSQL Serverに保存する必要があります。私はフィールドのサイズを増やしたくないので、この関数から「バイト」をINTフィールドから保存したいだけです。
これらのレコードの数百が一度に要求されているため、ループ内のUINT32をINTに変換するための最速の方法が必要です。左端のビットがUINT32で設定されている場合、intのサインビットを設定する必要があります(または、「繰り返し可能」なことは何でもしますが、サインビットはおそらく最も簡単です)。
言い換えれば、UINT32の4バイトを32ビットINTの4バイトにすることを望んでいます。 BitConverterクラスを使用できますが、それが最速の方法であるかどうかはわかりません。このようなチェックされていないエリアでこれを行う方が速いでしょうか:
UInt32 fld = 4292515959;
unchecked {
return (int)fld;
// -2451337
}
ここで逆の質問が尋ねられているのを見て、答えが逆になるのと同じであるかどうか疑問に思っていました。
解決
私はチェックされていないバージョンだと思います( unchecked((int)x)
)メソッドコールがないため、最速の方法です。より速い方法があるとは思わない。
ところで、 UInt32
ただの別の名前です uint
... 1つの方法では、パフォーマンスの面で別の方法で進むことと同じであるため、これは投稿したリンクと本当に同じです。
編集:ベンチマークのインスタンスを直接観察したことを覚えています checked
だった もっと早く よりも unchecked
(いいえ、それはデバッグビルドではなく、最適化を備えたリリースビルドでした)。なぜそれが起こったのかはわかりませんが、いずれにせよ、オーバーフローチェックを回すことで測定可能なものを獲得できるとは思わないでください。
他のヒント
unchecked((int)x)
constsのみが必要であり、チェックされてチェックされていない場合、同じ結果が生成されます(コードがコンパイルできる場合)。
たとえば、このコード
uint data = 4292515959;
int uncheckedData;
int checkedData;
unchecked {
uncheckedData = (int)data;
}
checkedData = (int)data;
Console.WriteLine(data);
Console.WriteLine(uncheckedData);
Console.WriteLine(checkedData);
この出力を生成します
4292515959 -2451337 -2451337
より簡潔にするために、このコードをコンパイルすることができます(同じ結果と同じ unchecked((int)data)
)
uint data = 4292515959;
checkedData = (int)data;
このコード(constに注意)はコンパイルできません(チェックされていない)
const uint data = 4292515959;
checkedData = (int)data;
このコードもコンパイルできません(チェックされていない必要があります)
checkedData = (int)4292515959;