锯齿状数组,带偏移量复制

Jagged array, copy with offset

我正在尝试将一个锯齿状数组复制到另一个具有给定偏移量的锯齿状数组中。我想到了以下内容:

private void CopyWithOffset(char[][] buffer, (int row, int col) offset)
{
    if (buffer == null) throw new ArgumentNullException(nameof(buffer));

    for (var row = 0; row < buffer.Length; row++)
    {
        try
        {
            for (var col = 0; col < buffer[row].Length; col++)
            {
                try
                {
                    _buffer[row + offset.row][col + offset.col] = buffer[row][col];
                }
                catch (IndexOutOfRangeException){}
            }
        } catch(IndexOutOfRangeException){}
    }
}

不幸的是它很慢。有什么方法可以更快吗?

中所述,异常处理非常昂贵,如果您将其用作代码中的正常控制流机制,它将使该代码 非常慢。

您只需编写代码即可轻松避免异常,这样一来它就不会使用超出范围的索引值:

private void CopyWithOffset(char[][] buffer, (int row, int col) offset)
{
    if (buffer == null) throw new ArgumentNullException(nameof(buffer));

    for (var row = 0; row < buffer.Length; row++)
    {
        for (var col = 0; col < buffer[row].Length ; col++)
        {
            int i = row + offset.row;

            if (i < _buffer.Length)
            {
                int j = col + offset.col;

                if (j < _buffer[i].Length)
                {
                    _buffer[i][j] = buffer[row][col];
                }
            }
        }
    }
}

正如@Steve 所建议的那样,避免超出索引并遍历数组的必要部分而不是遍历整个数组会带来很大的好处。

将它与Parallel.For和Array.Copy结合起来(应该利用SIMD扩展more info here)并且一个几乎具有快速阵列复制功能。

public static void CopyWithOffset(char[][] buffer, int x, int y)
{
    var rowStart = Math.Max(Math.Min(y, _buffer.Length), 0);
    var rowLenght = _buffer.Length + Math.Min(y, 0);

    Parallel.For(rowStart, rowLenght, row =>
    {
        var colStart = Math.Max(Math.Min(x, _buffer[row].Length), 0);
        var colLength = _buffer[row].Length + Math.Min(x, -1);

        Array.Copy(buffer[row - y], colStart - x, _buffer[row], colStart, colLength);
    });
}