在C#中优化if语句(a> 0 && b> 0 && a + b == c)

Tib*_*org 7 c# optimization if-statement

我目前正在做一些涉及邻接矩阵的图形计算,而我正在优化它的每一点.

我认为可以优化的说明之一是标题中的一个,它的原始形式:

if ((adjMatrix[i][k] > 0) && (adjMatrix[k][j] > 0) && (adjMatrix[i][k] + adjMatrix[k][j] == w))
Run Code Online (Sandbox Code Playgroud)

但为了方便起见,我将坚持标题中提供的表格:

if (a > 0 && b > 0 && a + b == c)
Run Code Online (Sandbox Code Playgroud)

我不喜欢的是> 0部分(是一个邻接矩阵,在它的初始形式中它只包含0和1,但随着程序的进展,零被从2开始的数字替换,直到没有更多的零.

我做了一个测试并删除了a和b的> 0部分,并且有了显着的改进.超过60088次迭代减少了792ms,从3672ms减少到2880ms,这是原始时间的78%,这对我来说非常好.

所以我的问题是:你能想到一些在C#中优化这样的语句并获得相同结果的方法吗?也许是一些按位操作或类似的东西,我对它们并不熟悉.

回答每一个想法,即使它不适合.我会自己做速度测试,让你知道结果.

编辑:这是一个编译器,我将在我的计算机上自己运行它.我刚刚描述的不是我抱怨的问题/瓶颈.它的当前形式的程序可以满足我的需求,但我只想推进它并使其尽可能基本和优化.希望这能澄清一点.

编辑我相信提供完整的代码它是一个有用的东西,所以在这里,但请记住我在下面的粗体说.我想严格关注if语句.该程序基本上采用邻接矩阵并存储所有存在的路径组合.然后根据一些系数进行排序和修剪,但我没有包括在内.

int w, i, j, li, k;
int[][] adjMatrix = Data.AdjacencyMatrix;
List<List<List<int[]>>> output = new List<List<List<int[]>>>(c);

for (w = 2; w <= 5; w++)
{
    int[] plan;

    for (i = 0; i < c; i++)
    {
        for (j = 0; j < c; j++)
        {
            if (j == i) continue;
            if (adjMatrix[i][j] == 0)
            {
                for (k = 0; k < c; k++) // 11.7%
                {
                    if (
                        adjMatrix[i][k] > 0 && 
                        adjMatrix[k][j] > 0 && 
                        adjMatrix[i][k] + adjMatrix[k][j] == w) // 26.4%
                    {
                        adjMatrix[i][j] = w;

                        foreach (int[] first in output[i][k])
                            foreach (int[] second in output[k][j]) // 33.9%
                            {
                                plan = new int[w - 1];
                                li = 0;

                                foreach (int l in first) plan[li++] = l;
                                plan[li++] = k;
                                foreach (int l in second) plan[li++] = l;

                                output[i][j].Add(plan);
                            }
                    }
                }

                // Here the sorting and trimming occurs, but for the sake of
                // discussion, this is only a simple IEnumerable<T>.Take()
                if (adjMatrix[i][j] == w)
                    output[i][j] = output[i][j].Take(10).ToList();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

添加了有关优化构建的分析器结果的注释.

顺便说一句,时间结果是通过这段代码获得的(没有排序和修剪,这大大增加了执行时间).我的测量中没有其他部分.在此代码之前有一个Stopwatch.StartNew(),紧接着是一个Console.WriteLine(EllapsedMilliseconds).

如果您想了解大小,邻接矩阵有406行/列.所以基本上只有for-instructions组合执行许多迭代,所以我没有很多优化选项.速度目前不是问题,但我想确保它已经准备就绪.

为了排除"优化其他部分"问题,本主题也有讨论的余地,但对于这个具体问题,我只想找到解决方案作为抽象问题/概念.它可以帮助我和其他人理解C#编译器如何工作并处理if语句和比较,这是我的目标.

Aki*_*nen 6

您可以替换为a>0 && b>0(a-1)|(b-1) >= 0符号的变量ab.

同样,条件x == w可以表示为(x - w)|(w - x) >= 0,因为当x != w表达式的左侧或右侧部分将切换符号位时,通过按位按位保留.放在一起的所有内容都将(a-1)|(b-1)|(a+b-w)|(w-a-b) >= 0表示为单一比较.

或者,将概率按升序排列可能会带来轻微的速度优势:

这样更容易(a|b)>=0还是(a+b)==w

  • 如果a = 0且b = 1会发生什么?(a | b)> 0 => True,但是(a> 0 && b> 0)=> False (2认同)