串联字节的C#列表[] [英] Concatenating a C# List of byte[]

查看:134
本文介绍了串联字节的C#列表[]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建需要被连接在一起,形成一个大的字节数组数字节数组 - 我宁愿不使用字节的所有[],但这里别无选择......



我添加每一个到一个列表,因为我创造他们,所以我只需要做好串联,一旦我拥有所有的byte []的,但我的问题是,什么是最好的实际上这样做的方法吗?



当我有一个清单,数目不详的byte []的和我想Concat的他们都在一起。



感谢


解决方案

  listOfByteArrs.SelectMany(byteArr => byteArr)。 .ToArray()

上面的代码将连接字节序列的序列为一个序列 - 和存储,结果在一个数组



虽然可读,这不是最大效率 - 这不是利用的事实,你的已经知道的长度生成的字节数组,因而可避免动态扩展 .ToArray()的实现,必然涉及到多种分配和阵列的副本。此外,的SelectMany 迭代器方面实现;这意味着大量的地段+接口调用这是相当缓慢的。然而,对于小十岁上下的数据集的大小,这是不太可能的事情。



如果的你需要一个更快的实现,你可以做到以下几点:

  VAR输出=新的字节[listOfByteArrs.Sum(ARR => arr.Length)]; 
INT writeIdx = 0;
的foreach(在listOfByteArrs VAR byteArr){
byteArr.CopyTo(输出,writeIdx);
writeIdx + = byteArr.Length;
}

或Martinho提示:

  VAR输出=新的字节[listOfByteArrs.Sum(ARR => arr.Length)]; 
使用(VAR流=新的MemoryStream(输出))
的foreach(在listOfByteArrs VAR字节为单位)
stream.Write(字节,0,bytes.Length);



有些时段:

  VAR listOfByteArrs = Enumerable.Range(1,1000)
。选择(I => Enumerable.Range(0,I)。选择(X =>(字节)x)的.ToArray ())了ToList();

使用短的方法来连接这些500500字节需要15毫秒,使用快速方法需要0.5ms的上我机 - YMMV,并注意对许多应用都大于足够快的多; - )



最后,你可以取代 Array.CopyTo 静态 Array.Copy ,低级别的缓冲器.BlockCopy 的MemoryStream 与预分配后缓冲区 - 这些都在我的测试中(64位.NET 4.0)执行几乎相同


I am creating several byte arrays that need to be joined together to create one large byte array - i'd prefer not to use byte[]'s at all but have no choice here...

I am adding each one to a List as I create them, so I only have to do the concatenation once I have all the byte[]'s, but my question is, what is the best way of actually doing this?

When I have a list with an unknown number of byte[]'s and I want to concat them all together.

Thanks.

解决方案

listOfByteArrs.SelectMany(byteArr=>byteArr).ToArray()

The above code will concatenate a sequence of sequences of bytes into one sequence - and store the result in an array.

Though readable, this is not maximally efficient - it's not making use of the fact that you already know the length of the resultant byte array and thus can avoid the dynamically extended .ToArray() implementation that necessarily involves multiple allocations and array-copies. Furthermore, SelectMany is implemented in terms of iterators; this means lots+lots of interface calls which is quite slow. However, for small-ish data-set sizes this is unlikely to matter.

If you need a faster implementation you can do the following:

var output = new byte[listOfByteArrs.Sum(arr=>arr.Length)];
int writeIdx=0;
foreach(var byteArr in listOfByteArrs) {
    byteArr.CopyTo(output, writeIdx);
    writeIdx += byteArr.Length;
}

or as Martinho suggests:

var output = new byte[listOfByteArrs.Sum(arr => arr.Length)];
using(var stream = new MemoryStream(output))
    foreach (var bytes in listOfByteArrs)
        stream.Write(bytes, 0, bytes.Length);

Some timings:

var listOfByteArrs = Enumerable.Range(1,1000)
    .Select(i=>Enumerable.Range(0,i).Select(x=>(byte)x).ToArray()).ToList();

Using the short method to concatenate these 500500 bytes takes 15ms, using the fast method takes 0.5ms on my machine - YMMV, and note that for many applications both are more than fast enough ;-).

Finally, you could replace Array.CopyTo with the static Array.Copy, the low-level Buffer.BlockCopy, or a MemoryStream with a preallocated back buffer - these all perform pretty much identically on my tests (x64 .NET 4.0).

这篇关于串联字节的C#列表[]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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