9

パフォーマンスに敏感な1つのスポットを除いて、デフォルトで算術演算をチェックしたいプロジェクトがあります。残念ながら、VB.Netには「チェックされていない」ブロックがありません。

理想的には、フレームワークは明示的にチェックされていない算術を持つある種の整数型を持っているでしょうが、私はそのようなものを見つけられませんでした。式ツリーにはチェックされていない操作のバイナリ式があることがわかりましたが、デリゲートのオーバーヘッドにより、チェックされていない利点(および一部)が相殺されます。

現在、演算を実行する前に入力をUInt64 / Int64に変換してから、元に戻しています(ビット単位のAndを使用して範囲内を確保します)。チェックされていない演算(プロファイリングによる)よりも約50%遅くなります。

算術演算がチェックされていないプロジェクトに算術演算の影響を受けやすい部分を移動することは機能するかもしれませんが、それ自体にすべてのアセンブリを与えるのはやり過ぎのようです。

4

3 に答える 3

6

私はこれが古いことを知っていますが、最近、チェックされていないものを使用するいくつかのC#コードを変換する必要があり、それをどのように行ったかを共有したいと思いました。これは純粋なVBコードであり、(プロジェクト全体のオプションではなく)必要に応じてスコープを設定できます。

秘訣は、Longフィールドと2つのIntegerフィールドを含む構造を作成することです。次に、StructLayout属性とFieldOffset属性を使用して、longと2つの整数の和集合を作成します。フィールドはプライベートにすることができます(すべきです)。拡大CType演算子を使用して、Longから構造体に変換し、構造体から整数に変換します(低整数値を使用)。+、-、*などの演算子のオーバーロードを追加します...そしてpresto!VBのチェックされていない算術!

Strilancが指摘したように、long値がlongの範囲外になると、それでもオーバーフローします。ただし、チェックされていないものが使用される多くの状況ではかなりうまく機能します。

次に例を示します。

<StructLayout(LayoutKind.Explicit)>
Public Structure UncheckedInteger

    <FieldOffset(0)>
    Private longValue As Long
    <FieldOffset(0)>
    Private intValueLo As Integer
    <FieldOffset(4)>
    Private intValueHi As Integer

    Private Sub New(newLongValue As Long)
        longValue = newLongValue
    End Sub

    Public Overloads Shared Widening Operator CType(value As Long) As UncheckedInteger
        Return New UncheckedInteger(value)
    End Operator

    Public Overloads Shared Widening Operator CType(value As UncheckedInteger) As Long
        Return value.longValue
    End Operator

    Public Overloads Shared Widening Operator CType(value As UncheckedInteger) As Integer
        Return value.intValueLo
    End Operator

    Public Overloads Shared Operator *(x As UncheckedInteger, y As Integer) As UncheckedInteger
        Return New UncheckedInteger(x.longValue * y)
    End Operator

    Public Overloads Shared Operator Xor(x As UncheckedInteger, y As Integer) As UncheckedInteger
        Return New UncheckedInteger(x.longValue Xor y)
    End Operator

    ' Any other operator overload you need...
End Structure

次のようなコードの構造を使用します。

Dim x As UncheckedInteger = 2147483647
Dim result As Integer = x * 2  ' This would throw OverflowException using just Integers

Console.WriteLine(result.ToString())  ' -2

結果をUncheckedIntegerに割り当てる前に、計算がオーバーフローしないように注意してください。同じ手法を使用して、UncheckedShort構造とUncheckedByte構造を作成できます。

于 2013-03-26T23:47:49.890 に答える
2

個人的には、これを独自のアセンブリに残すことは、特に非常に小さなアセンブリになるため、良いオプションだと思います。これにより、このアセンブリをいつでも簡単に再生成できるため、メンテナンスが容易になります。チェックされていないフラグが設定された別のアセンブリを作成し、パフォーマンスに敏感なコードをそこに配置するだけです。

于 2010-03-08T17:22:30.747 に答える
0

最近、VB.NETでチェックされていない整数操作用のnugetパッケージを作成しました。nugetパッケージVBMath.UncheckedまたはGithubリポジトリSystem.Runtime.Extensions.Uncheckedを参照してください。

Using System.Numerics

' this will not throw
Dim value = UncheckedInteger.Add(Integer.MaxValue, 1)
于 2020-04-25T09:55:56.937 に答える