缓存友好且速度更快 - `InvokeMe()`

Cache friendly and faster way faster - `InvokeMe()`

我想知道这是否真的是最快的方法。我希望它尽可能快,缓存友好,并提供良好的时间复杂度。

演示:https://dotnetfiddle.net/BUGz8s

private static void InvokeMe() 
{
    int hz = horizontal.GetLength(0) * horizontal.GetLength(1);
    int vr = vertical.GetLength(0) * vertical.GetLength(1);
    int hzcol = horizontal.GetLength(1);
    int vrcol = vertical.GetLength(1);
    
    //Determine true from Horizontal information:
    for (int i = 0; i < hz; i++)
    {
        if(horizontal[i / hzcol, i % hzcol] == true)
           System.Console.WriteLine("True, on position: {0},{1}", i / hzcol, i % hzcol);
    }

    //Determine true position from vertical information:
    for (int i = 0; i < vr; i++)
    {
        if(vertical[i / vrcol, i % vrcol] == true)
           System.Console.WriteLine("True, on position: {0},{1}", i / vrcol, i % vrcol);
    }
}

我阅读的页数:


编辑: 代码示例现在更接近我正在处理的内容。它是关于从 N*N 网格中确定一个真实点 x,y。可用的信息是:水平和垂直二维数组。

不要造成混淆。想象一下,随着时间的推移,某些垂直或水平位置被设置为 True。这目前非常有效。我所关心的是,当前的方法是像这样对每个二维数组使用一个 for 循环,而不是对每个二维数组使用两个 for 循环.

你考虑过吗

for (int i = 0; i < row; i++)
{
    for (int j = 0; j < col; j++)
    {
        Console.Write(string.Format("{0:00} ", matrix[i, j]));
        Console.Write(Environment.NewLine + Environment.NewLine);
    }
}

它基本上与您的循环相同,但没有 /% 编译器可能会优化也可能不会优化。

使用一个循环和嵌套循环的方法的时间复杂度是相同的 - O(row * col)(对于 row == col 是 O(n^2),如您的示例对于这两种情况),因此执行时间的差异将来自操作常量(因为遍历方向应该相同)。您可以使用 BenchmarkDotNet 来衡量这些。下一个基准:

[SimpleJob]
public class Loops
{
    int[, ] matrix = new int[10, 10];
    [Benchmark]
    public void NestedLoops()
    {
        int row = matrix.GetLength(0);
        int col = matrix.GetLength(1);
        for (int i = 0; i < row ; i++)
        for (int j = 0; j < col ; j++)
        {
            matrix[i, j] = i * row + j + 1;
        }
    }
    
    [Benchmark]
    public void SingleLoop()
    {
        int row = matrix.GetLength(0);
        int col = matrix.GetLength(1);
        var l = row * col; 
        for (int i = 0; i < l; i++)
        {
            matrix[i / col, i % col] = i + 1;
        }
    }
}

在我的机器上给出:

Method Mean Error StdDev Median
NestedLoops 144.5 ns 2.94 ns 4.58 ns 144.7 ns
SingleLoop 578.2 ns 11.37 ns 25.42 ns 568.6 ns

使单循环实际上更慢。

如果您将循环体更改为某些“虚拟”操作 - 例如增加一些外部变量或更新 martix 的固定(例如第一个)元素,您会发现两个循环的性能大致相同。