简体   繁体   English

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

[英]Jagged array, copy with offset

I am trying to copy one jagged array into another jagged array with given offset. 我正在尝试将一个锯齿状数组复制到具有给定偏移量的另一个锯齿状数组中。 I came up with the following: 我想出了以下几点:

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){}
    }
}

Unfortunately it is very slow. 不幸的是,它非常慢。 Is there any way to do it faster? 有什么办法可以更快地做到这一点?

As noted in this comment , exception handling is very expensive, and if you use it as a normal control-flow mechanism in your code, it will make that code very slow. 本注释中所述 ,异常处理非常昂贵,如果将其用作代码中的常规控制流机制,它将使该代码非常慢。

You can easily avoid exceptions by just writing the code so that it doesn't use out-of-range index values in the first place: 您只需编写代码就可以轻松避免异常,这样一来,它就不会使用超出范围的索引值:

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];
                }
            }
        }
    }
}

As suggested by @Steve avoiding going out of index and iterating over necessary part of an array instead of iterating over the entire array pays of greatly. 正如@Steve所建议的那样,避免超出索引并遍历数组的必要部分,而不是遍历整个数组需要付出巨大的代价。

Combine it with Parallel.For and Array.Copy (it should make use of SIMD extension more info here ) and one pretty much have lighting fast array copy function. 将其与Parallel.For和Array.Copy结合使用(应该在此处使用SIMD扩展名更多信息 ),其中的一个具有照明快速数组复制功能。

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);
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM