Dan*_*dor 9 .net c# optimization
int X = a-b;
int d = Math.Abs(X);
Run Code Online (Sandbox Code Playgroud)
我很确定.NET不会内联.那么,我会做if(),还是还有其他一些鲜为人知的技巧?
Hug*_*une 17
我做了一些性能测试,以确定你是否可以使用除标准Math.Abs之外的其他东西来节省时间.
执行所有这些2000000000次后的结果(i
从-1000000000到+1000000000,所以没有溢出):
Math.Abs(i) 5839 ms Factor 1
i > 0 ? i : -i 6395 ms Factor 1.09
(i + (i >> 31)) ^ (i >> 31) 5053 ms Factor 0.86
Run Code Online (Sandbox Code Playgroud)
(这些数字因不同的运行而有所不同)
基本上你可以得到一个非常小的改善Math.Abs
,但没有什么了不起的.
有点破解你可以减少Math.Abs所需的一些时间,但可读性严重受损.
使用简单的分支,您实际上可以更慢.在我看来总的来说不值得.
所有测试均在32位操作系统,Net 4.0,VS 2010,发布模式下运行,不附带调试器.
这是实际的代码:
class Program
{
public static int x; // public static field.
// this way the JITer will not assume that it is
// never used and optimize the wholeloop away
static void Main()
{
// warm up
for (int i = -1000000000; i < 1000000000; i++)
{
x = Math.Abs(i);
}
// start measuring
Stopwatch watch = Stopwatch.StartNew();
for (int i = -1000000000; i < 1000000000; i++)
{
x = Math.Abs(i);
}
Console.WriteLine(watch.ElapsedMilliseconds);
// warm up
for (int i = -1000000000; i < 1000000000; i++)
{
x = i > 0 ? i : -i;
}
// start measuring
watch = Stopwatch.StartNew();
for (int i = -1000000000; i < 1000000000; i++)
{
x = i > 0 ? i : -i;
}
Console.WriteLine(watch.ElapsedMilliseconds);
// warm up
for (int i = -1000000000; i < 1000000000; i++)
{
x = (i + (i >> 31)) ^ (i >> 31);
}
// start measuring
watch = Stopwatch.StartNew();
for (int i = -1000000000; i < 1000000000; i++)
{
x = (i + (i >> 31)) ^ (i >> 31);
}
Console.WriteLine(watch.ElapsedMilliseconds);
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 15
JIT在某些情况下执行内联.我不知道它是否内联Math.Abs
......但你确认这实际上是一个性能问题吗?在您知道需要之前不要进行微观优化,然后通过以下方式测量性能增益:
int d = X > 0 ? X : -X;
Run Code Online (Sandbox Code Playgroud)
验证它真的值得.
正如由Anthony指出,上面就不会(通常)为工作int.MinValue
,如-int.MinValue == int.MinValue
,而Math.Abs
将引发OverflowException
.您可以使用选中的算法在直接C#中强制执行此操作:
int d = X > 0 ? X : checked(-X);
Run Code Online (Sandbox Code Playgroud)
对于它的价值,32位带符号,2的补码格式int的绝对值通常是这样实现的:
abs(x)=(x ^(x >> 31)) - (x >> 31)