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

查看:127
本文介绍了两个或两个以上字节数组在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 而不是<$ C $的C> System.Array.Copy 。它的速度更快。

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

我计时每在一个循环中建议的方法使用的每10个字节的3个数组执行1万次。下面是结果:

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&LT;字节>使用C#的产量运营商 - 0.0781270秒

  4. 的IEnumerable&LT;字节>使用LINQ的Concat的&LT;> - 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&LT;字节>使用C#的产量运营商 - 0.0625012秒

  4. 的IEnumerable&LT;字节>使用LINQ的Concat的&LT;> - 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&LT;字节>使用C#的产量运营商 - 0.0625012秒

  4. 的IEnumerable&LT;字节>使用LINQ的Concat的&LT;> - 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

最后,我增加每个数组的大小为1万台,并重新运行测试,执行每个循环的 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&LT;字节>使用C#的产量运营商 - 0秒。

  4. 的IEnumerable&LT;字节>使用LINQ的Concat的&LT;> - 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);

但是,如果你可以使用的IEnumerable&LT;字节&GT; DEFINITELY preFER LINQ的Concat的&LT; >方法。这仅比C#的产量运营商稍微慢一点,但更简洁,更优雅。

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;

要乔恩斯基特的关于后续数据结构的迭代(字节数组与IEnumerable的&LT;字节>)点,我再跑到最后的时间测试(1万台,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&LT;字节>使用C#的产量运营商 - 551.7150161秒

  4. 的IEnumerable&LT;字节>使用LINQ的Concat的&LT;> - 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天全站免登陆