在 VB.Net 中进行未经检查的整数加法的最快方法?
我有一个项目,我想默认检查算术,除了一个性能敏感点之外。不幸的是,VB.Net 没有“未经检查”的块。
理想情况下,框架应该有某种带有显式未经检查的算术的整数类型,但我没有找到类似的东西。我确实发现表达式树具有用于未经检查的操作的二进制表达式,但是委托开销抵消了未经检查的优势(然后是一些)。
目前,我在进行算术之前将输入转换为 UInt64/Int64,然后转换回来(使用按位 And 以确保在范围内)。它比未经检查的算术慢大约 50%(根据分析)。
将算术敏感部分移到具有未经检查算术的项目中可能可行,但将其单独提供一个程序集似乎有点过分了。
I have a project where I want to have checked arithmetic by default, except for one performance sensitive spot. Unfortunately, VB.Net doesn't have an 'unchecked' block.
Ideally the framework would have some sort of integer type with explicitly unchecked arithmetic, but I didn't find anything like that. I did find that expression trees have binary expressions for unchecked operations, but the delegate overhead cancels out the unchecked advantage (and then some).
Currently I'm converting the inputs to UInt64/Int64 before doing the arithmetic, then converting back (with a bitwise And to ensure in-range). It's about 50% slower than unchecked arithmetic (according to profiling).
Moving the arithmetic-sensitive part to a project with unchecked arithmetic might work, but it seems like overkill to give it an assembly all to itself.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我知道这已经很旧了,但我最近需要转换一些未检查的 C# 代码,我想我应该分享一下我是如何做到的。它是纯 VB 代码,可以根据需要确定范围(而不是项目范围的选项)。
诀窍是创建一个包含一个 Long 字段和两个 Integer 字段的结构。然后使用 StructLayout 和 FieldOffset 属性创建长整数和两个整数的并集。这些字段可以(应该)是私有的。使用加宽 CType 运算符将 Long 转换为结构体,以及从结构体转换为 Integer(使用低位整数值)。添加 +、-、* 等运算符重载...然后很快! VB 中未经检查的算术!
正如 Strilanc 指出的那样,如果 long 值超出了 long 的范围,它仍然会溢出。但它在很多使用 unchecked 的情况下效果很好。
下面是一个示例:
在如下代码中使用结构:
在将结果分配给 UncheckedInteger 之前,请小心计算不要溢出。您可以使用相同的技术创建 UncheckedShort 和 UncheckedByte 结构。
I know this is old, but I recently needed to convert some C# code that used unchecked and I thought I'd share how I did it. It's pure VB code and can be scoped however you need (rather than a project-wide option).
The trick is to create a structure that contains a Long field and two Integer fields. Then use StructLayout and FieldOffset attributes to create a union of the long and the two integers. The fields can (should) be private. Use widening CType operators to convert from a Long to the structure and from the structure to an Integer (using the low integer value). Add operator overloads for +, -, *, etc... and presto! unchecked arithmetic in VB!
Sort of... it will still overflow, as Strilanc pointed out, if the long value goes outside the range for longs. But it works pretty well for a lot of situations where unchecked is used.
Here's an example:
Use the structure in code like this:
Careful that your calculations don't overflow before assigning the result to an UncheckedInteger. You could create UncheckedShort and UncheckedByte structures using the same technique.
就我个人而言,我认为将其保留在自己的程序集中,特别是因为它是一个如此小的程序集,是一个不错的选择。这使得维护更加容易,因为可以随时轻松地重新生成该组件。只需制作一个标记为未选中的单独程序集,然后将性能敏感的代码放在那里即可。
Personally, I think leaving this in its own assembly, especially since it'll be such a small assembly, is a good option. This makes maintenance easier, since it's easy to regenerate this assembly at any time. Just make a separate assembly flagged unchecked, and put your performance-sensitive code there.
我最近在 VB.NET 中为未经检查的整数运算创建了一个 nuget 包,请参阅 nuget 包 VBMath。未选中或 Github 存储库System.Runtime.Extensions.Unchecked。
I've recently created a nuget package for unchecked integer operations in VB.NET, see nuget package VBMath.Unchecked or Github repository System.Runtime.Extensions.Unchecked.