在 C# 中组合两个或多个字节数组的最佳方法 [英] Best way to combine two or more byte arrays in C#

查看:57
本文介绍了在 C# 中组合两个或多个字节数组的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 C# 中有 3 个字节数组,我需要将它们合并为一个.完成此任务的最有效方法是什么?

I have 3 byte arrays in C# that I need to combine into one. What would be the most efficient method to complete this task?

推荐答案

对于原始类型(包括字节),请使用 System.Buffer.BlockCopy 而不是 System.Array.Copy.它更快.

For primitive types (including bytes), use System.Buffer.BlockCopy instead of System.Array.Copy. It's faster.

我使用 3 个每个 10 字节的数组对循环中的每个建议方法进行计时 100 万次.结果如下:

I timed each of the suggested methods in a loop executed 1 million times using 3 arrays of 10 bytes each. Here are the results:

  1. 使用 System.Array.Copy 的新字节数组 - 0.2187556 秒
  2. 使用 System.Buffer.BlockCopy 的新字节数组 - 0.1406286 秒
  3. IEnumerable 使用 C# yield 运算符 - 0.0781270 秒
  4. IEnumerable 使用 LINQ 的 Concat<> - 0.0781270 秒
  1. New Byte Array using System.Array.Copy - 0.2187556 seconds
  2. New Byte Array using System.Buffer.BlockCopy - 0.1406286 seconds
  3. IEnumerable<byte> using C# yield operator - 0.0781270 seconds
  4. IEnumerable<byte> using LINQ's Concat<> - 0.0781270 seconds

我将每个数组的大小增加到 100 个元素并重新运行测试:

I increased the size of each array to 100 elements and re-ran the test:

  1. 使用 System.Array.Copy 的新字节数组 - 0.2812554 秒
  2. 使用 System.Buffer.BlockCopy 的新字节数组 - 0.2500048 秒
  3. IEnumerable 使用 C# yield 运算符 - 0.0625012 秒
  4. IEnumerable 使用 LINQ 的 Concat<> - 0.0781265 秒
  1. New Byte Array using System.Array.Copy - 0.2812554 seconds
  2. New Byte Array using System.Buffer.BlockCopy - 0.2500048 seconds
  3. IEnumerable<byte> using C# yield operator - 0.0625012 seconds
  4. IEnumerable<byte> using LINQ's Concat<> - 0.0781265 seconds

我将每个数组的大小增加到 1000 个元素并重新运行测试:

I increased the size of each array to 1000 elements and re-ran the test:

  1. 使用 System.Array.Copy 的新字节数组 - 1.0781457 秒
  2. 使用 System.Buffer.BlockCopy 的新字节数组 - 1.0156445 秒
  3. IEnumerable 使用 C# yield 运算符 - 0.0625012 秒
  4. IEnumerable 使用 LINQ 的 Concat<> - 0.0781265 秒
  1. New Byte Array using System.Array.Copy - 1.0781457 seconds
  2. New Byte Array using System.Buffer.BlockCopy - 1.0156445 seconds
  3. IEnumerable<byte> using C# yield operator - 0.0625012 seconds
  4. IEnumerable<byte> using LINQ's Concat<> - 0.0781265 seconds

最后,我将每个数组的大小增加到 100 万个元素并重新运行测试,每个循环执行 4000 次:

Finally, I increased the size of each array to 1 million elements and re-ran the test, executing each loop only 4000 times:

  1. 使用 System.Array.Copy 的新字节数组 - 13.4533833 秒
  2. 使用 System.Buffer.BlockCopy 的新字节数组 - 13.1096267 秒
  3. IEnumerable 使用 C# yield 运算符 - 0 秒
  4. IEnumerable 使用 LINQ 的 Concat<> - 0 秒
  1. New Byte Array using System.Array.Copy - 13.4533833 seconds
  2. New Byte Array using System.Buffer.BlockCopy - 13.1096267 seconds
  3. IEnumerable<byte> using C# yield operator - 0 seconds
  4. IEnumerable<byte> using LINQ's Concat<> - 0 seconds

因此,如果您需要一个新的字节数组,请使用

So, if you need a new byte array, use

byte[] rv = new byte[a1.Length + a2.Length + a3.Length];
System.Buffer.BlockCopy(a1, 0, rv, 0, a1.Length);
System.Buffer.BlockCopy(a2, 0, rv, a1.Length, a2.Length);
System.Buffer.BlockCopy(a3, 0, rv, a1.Length + a2.Length, a3.Length);

但是,如果您可以使用 IEnumerableDEFINITELY 更喜欢 LINQ 的 Concat<> 方法.它只比 C# 的 yield 操作符慢一点,但更简洁、更优雅.

But, if you can use an IEnumerable<byte>, DEFINITELY prefer LINQ's Concat<> method. It's only slightly slower than the C# yield operator, but is more concise and more elegant.

IEnumerable<byte> rv = a1.Concat(a2).Concat(a3);

如果您有任意数量的数组并使用 .NET 3.5,您可以使 System.Buffer.BlockCopy 解决方案更通用,如下所示:

If you have an arbitrary number of arrays and are using .NET 3.5, you can make the System.Buffer.BlockCopy solution more generic like this:

private byte[] Combine(params byte[][] arrays)
{
    byte[] rv = new byte[arrays.Sum(a => a.Length)];
    int offset = 0;
    foreach (byte[] array in arrays) {
        System.Buffer.BlockCopy(array, 0, rv, offset, array.Length);
        offset += array.Length;
    }
    return rv;
}

*注意:上面的块需要你在顶部添加以下命名空间才能工作.

*Note: The above block requires you adding the following namespace at the the top for it to work.

using System.Linq;

对于 Jon Skeet 关于后续数据结构迭代的观点(字节数组与 IEnumerable<byte>),我重新运行了最后一次计时测试(100 万个元素,4000 次迭代),添加了一个循环来遍历整个每次通过的数组:

To Jon Skeet's point regarding iteration of the subsequent data structures (byte array vs. IEnumerable<byte>), I re-ran the last timing test (1 million elements, 4000 iterations), adding a loop that iterates over the full array with each pass:

  1. 使用 System.Array.Copy 的新字节数组 - 78.20550510 秒
  2. 使用 System.Buffer.BlockCopy 的新字节数组 - 77.89261900 秒
  3. IEnumerable 使用 C# yield 运算符 - 551.7150161 秒
  4. IEnumerable 使用 LINQ 的 Concat<> - 448.1804799 秒
  1. New Byte Array using System.Array.Copy - 78.20550510 seconds
  2. New Byte Array using System.Buffer.BlockCopy - 77.89261900 seconds
  3. IEnumerable<byte> using C# yield operator - 551.7150161 seconds
  4. IEnumerable<byte> using LINQ's Concat<> - 448.1804799 seconds

关键是,了解结果数据结构的创建和使用的效率非常很重要.仅仅关注创建的效率可能会忽略与使用相关的低效率.感谢乔恩.

The point is, it is VERY important to understand the efficiency of both the creation and the usage of the resulting data structure. Simply focusing on the efficiency of the creation may overlook the inefficiency associated with the usage. Kudos, Jon.

这篇关于在 C# 中组合两个或多个字节数组的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆