从数组中检索恒定的字节数

时间:2014-07-08 06:15:04

标签: c# arrays

我有一个巨大的byte[] data数组。我想采用特定的字节数(考虑为Blocksize)并对其进行一些操作,并在新数组中一个接一个地添加每个块的所有结果。

这是我的代码:

        int j = 0;
        int number_of_blocks = (data.Length) / 16;
        byte[] one_block = new byte[16];
        byte[] one_block_return = new byte[16];
        byte[] all_block_return = new byte[data.Length];

        for (int i = 0; i < number_of_blocks; i++)
        {
            Array.Copy(data, j, one_block, 0, 16);
            one_block_return = one_block_operation(one_block);
            Array.Copy(one_block_return, 0, all_block_return, j, 16);
            Array.Clear(one_block, 0, one_block.Length);
            j = j + 16;
        }

此代码的唯一问题是它太慢,因为我的数据数组非常大。所以我期待更换Array.Copy(),这比这更快,或者有人有更好的方法来做到这一点。我想知道有多少方法可以做到这一点,并希望看到编码的变化。

-Thanks

1 个答案:

答案 0 :(得分:1)

简单并行化怎么样?

int number_of_blocks = (int)Math.Ceiling((double)data.Length / 16);
byte[] all_block_return = new byte[data.Length];

Parallel.For(0, number_of_blocks - 1, block_no =>
              {
                  var blockStart = block_no * 16; // 16 - block size
                  var blockLength = Math.Min(16, data.Length - blockStart);
                  byte[] one_block = new byte[16];
                  byte[] one_block_return = new byte[16];

                  Array.Copy(data, blockStart, one_block, 0, blockLength);

                  one_block_return = one_block_operation(one_block);

                  Array.Copy(one_block_return, 0, all_block_return, blockStart, blockLength);
              });

有可能one_block_operationdata, blockStart, blockStart + blockLength个参数代替缓冲区(one_block)?您可以避免Array.Copy之一。

修改 下面是它的工作原理: 首先,我们需要计算数量或块。然后使用指定的参数执行Parallel.For:start index,end index和传递一个参数的委托 - 当前处理的索引。在我们的例子中,索引被认为是块数。相当于此代码的是:

for (var block_no = 0, block_no <= number_of_blocks - 1; block_no++) {
    delegate(block_no);
}

唯一的区别是 Parallerl.For在多个线程中运行该循环。线程计数不固定 - 它取决于ThreadPool大小(根据MSDN,它还取决于许多因素)。

由于每个deletage都可以独立调用(我们不知道调用deletagtes的顺序)我们不能使用变量来存储deletegate之外的当前块启动索引(就像你将它存储在for循环外)。但是如果我们知道块的当前块数和大小,那么计算块起始索引非常容易(并且在第8行完成)。

不 - 你不能跳过第9行或用const值16替换它。为什么?考虑以下顺序:

  

1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17

我们可以将这个序列分成两个大小为16的块: 第1名:[1-16] 第二名:[17]

所以,就像你看到的那样 - 第二个块不包含16个元素,但只有1.第9行计算实际块大小/长度,因此你可以轻松避免IndexOutOfBoundException。