在VB.Net中进行未经检查的整数加法的最快方法?

Cra*_*ney 9 .net vb.net math unchecked

我有一个项目,我想默认检查算术,除了一个性能敏感点.不幸的是,VB.Net没有"未经检查"的块.

理想情况下,框架会有一些带有显式未经检查算术的整数类型,但我没有找到类似的东西.我确实发现表达式树具有用于未经检查的操作的二进制表达式,但是委托开销取消了未经检查的优势(然后是一些).

目前我在进行算术运算之前将输入转换为UInt64/Int64,然后转换回(使用按位并确保范围内).它比未经检查的算术慢50%(根据分析).

使用未经检查的算术将算术敏感部分移动到项目可能会起作用,但是为它自己提供一个程序集似乎有些过分.

Tim*_*bay 5

我知道这是旧的,但我最近需要转换一些使用未经检查的C#代码,我想我会分享我是如何做到的.它是纯VB代码,可以根据需要设置范围(而不是项目范围的选项).

诀窍是创建一个包含Long字段和两个Integer字段的结构.然后使用StructLayout和FieldOffset属性创建long和两个整数的并集.这些字段可以(应该)是私有的.使用扩展的CType运算符从Long转换为结构,从结构转换为Integer(使用低整数值).为+, - ,*等添加运算符重载...并且presto!VB中未经检查的算术!

如果Strilanc指出,如果长值超出了多头的范围,它仍会溢出...... 但是对于很多使用未经检查的情况,它的效果非常好.

这是一个例子:

<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
Run Code Online (Sandbox Code Playgroud)

在代码中使用这样的结构:

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

Console.WriteLine(result.ToString())  ' -2
Run Code Online (Sandbox Code Playgroud)

在将结果分配给UncheckedInteger之前,请注意计算不会溢出.您可以使用相同的技术创建UncheckedShort和UncheckedByte结构.


Ree*_*sey 2

就我个人而言,我认为将其保留在自己的程序集中,特别是因为它是一个如此小的程序集,是一个不错的选择。这使得维护更加容易,因为可以随时轻松地重新生成该组件。只需制作一个标记为未选中的单独程序集,然后将性能敏感的代码放在那里即可。

  • 我做了一些稍微不同的事情:我用未经检查的算术编写类型并将它们放入未经检查的程序集中。现在我有 ModByte/ModInt16/ModInt32/ModInt64 ,未经检查的程序集肯定不会慢慢吸收代码。 (4认同)