当前位置: 首页 > 编程语言 > C#

FastIntegerABS函数分享

时间:2023-04-10 11:56:44 C#

FastIntegerABSfunctionintX=ab;intd=Math.Abs??(X);我很确定.NET不会内联。那么,我会做一个if(),还是有其他一些鲜为人知的技巧?JIT在某些情况下执行内联。我不知道它是否内联Math.Abs??...但是您确认这实际上是一个性能问题吗?在知道需要之前不要进行微优化,然后通过以下方式衡量性能增益:intd=X>0?X:-X;验证它是否真的值得。正如Anthony指出的那样,上面的内容(通常)不会对int.MinValue起作用,因为-int.MinValue==int.MinValue,而Math.Abs??会抛出OverflowException。您可以使用检查算法在直接C#中强制执行此操作:intd=X>0?X:选中(-X);我做了一些性能测试,看看你是否可以使用标准Math.Abs??以外的东西来节省时间。完成所有这些操作2000000000次后的结果(我从-1000000000到+1000000000,所以没有溢出):Math.Abs??(i)5839msFactor1i>0?i:-i6395msFactor1.09(i+(i>>31))^(i>>31)5053msFactor0.86(这些数字因运行而异)基本上你可以略微改进Math.Abs??,但没有什么到Math.Abs??。通过一些技巧,您可以减少Math.Abs??花费的一些时间,但可读性会受到严重影响。您实际上可以使用简单的分支来减慢速度。总的来说在我看来不值得。所有测试都在32位操作系统、Net4.0、VS2010上以发布模式运行,没有附加调试器。这是实际的代码:classProgram{publicstaticintx;//公共静态字段。//这样JITer就不会假定它//从未使用过并优化整个循环staticvoidMain(){//预热for(inti=-1000000000;i0?i:-i;}//开始测量watch=Stopwatch.StartNew();for(inti=-1000000000;i0?i:-i;}Console.WriteLine(watch.ElapsedMilliseconds);//预热for(inti=-1000000000;i>31))^(i>>31);}//开始测量watch=Stopwatch.StartNew();for(inti=-1000000000;i>31))^(i>>31);}Console.WriteLine(watch.ElapsedMilliseconds);控制台.ReadLine();对于它的价值,32位有符号,2的补码格式int绝对值通常是这样实现的:abs(x)=(x^(x>>31))-(x>>31)我只是看看是否它小于零并乘以-1计算绝对值而不分支,参见http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs。虽然.Net支持内联,但我怀疑Math.Abs??()是否会被编译器解释为内联的候选对象。这是Reflector提供的int重载的实现。publicstaticintAbs(intvalue){if(value>=0){返回值;}返回AbsHelper(值);}privatestaticintAbsHelper(intvalue){if(value==-2147483648){thrownewOverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum"));}返回值;其他整数类型的重载是相似的。float和double重载是外部调用,而decimal重载使用它自己的实现,它构造一个新的实例。哎哟!C#内联Math.Abs??。这有效:以上是C#学习教程:FastIntegerABSfunction分享的全部内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注---intx=12;整数y=17;intz=Math.Abs??(x-y);控制台.WriteLine(z);//outputs5本文摘自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: