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

标签 .net vb.net math unchecked

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

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

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

将算术敏感部分移动到具有未经检查的算术的项目中可能会奏效,但将其全部单独提供给它似乎有点矫枉过正。

最佳答案

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

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

有点......它仍然会溢出,正如 Strilanc 指出的那样,如果 long 值超出 long 的范围。但它适用于许多使用 unchecked 的情况。

这是一个例子:

<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 结构。

关于.net - 在 VB.Net 中进行未经检查的整数加法的最快方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2403154/

相关文章:

.net - WCF 返回数组而不是列表即使集合类型 == Generic.List

.net - 处理与.NET Web服务内的客户端的连接断开-可能吗?

c# - 当 PC 从 sleep 中唤醒时,计时器会发生什么情况?

python - 截断 pandas df 中值的小数位

algorithm - 找到圆锥的顶点,已知圆锥内切的球体

c# - 如何从 `new Func<T>() { ... }?` 获取结果

c# - Entity Framework - 如何从联结表中删除数据

Java Windows-1252 错误字符

vb.net - 如何获取远程文件的最后修改值?

algorithm - 判断两条射线是否相交