【问题标题】:Fast way to copy part of an array into a List?将部分数组复制到列表中的快速方法?
【发布时间】:2014-06-18 05:57:35
【问题描述】:

C# 的 List 有一组 CopyTo 函数,这些函数将使用快速内存​​块复制将其内部数组的内容提取到另一个数组中。

有没有办法反过来呢?它可能看起来像......

var buffer = new List<byte>();
buffer.AddRange(afewbytes);
buffer.AddFromArray(myArray, startIndex, countBytesToCopy);
buffer.AddRange(afewmorebytes);

由于我的 List 是 List 种类,我希望避免一个逐字节复制的循环。

【问题讨论】:

    标签: c# .net arrays performance memory


    【解决方案1】:

    要复制数组的一部分,请将数组包装在ArraySegment 中,指定段的索引和计数。使用列表的AddRange 方法将ArraySegment 添加到列表中。 AddRange 将使用ArraySegment.CopyTo,它使用Array.Copy,即fast

    【讨论】:

    • 这应该是公认的答案!
    【解决方案2】:

    如果集合实现了ICollection&lt;T&gt;List&lt;T&gt;(IEnumerable&lt;T&gt;) 构造函数将使用ICollection&lt;T&gt;.CopyTobyte[] 会这样做。

    如果您只想提取数组的部分,这不会直接提供帮助,但是您可以创建自己的 ByteArraySegment 类实现 ICollection&lt;byte&gt; 并使用 @ 实现 CopyTo 操作987654328@ 或其他:

    public class ByteArraySegment : ICollection<byte>
    { 
        private readonly byte[] array;
        private readonly int start;
        private readonly int count;
    
        public ByteArraySegment(...)
        {
            // Obvious code
        }
    
        public void CopyTo(byte[] target, int index)
        { 
            Buffer.BlockCopy(array, start, target, index, count);
        }
    
        // Other ICollection<T> members
    }
    

    然后:

    List<byte> bytes = new List<byte>(new ByteArraySegment(myArray, start, count));
    

    (或者使用AddRange,同样优化。)

    【讨论】:

    • 非常感谢!我已经编辑了我的问题,以澄清我正在寻找一个高效的 Add 而不是构造函数,但从 David 回答的 cmets 的外观来看,你的类也应该适用于 AddRange。
    • 我们真的确定我们可以信任这个 Jon Skeet 小伙子吗? ;)
    • 你永远无法确定 Jon Skeet...有人说,他甚至不是真的!
    【解决方案3】:

    List.AddRange(myArray) 应该很高效。

    From MSDN: "如果新的 Count(当前 Count 加上集合的大小)将大于 Capacity,则通过自动重新分配内部数组以容纳新元素来增加 List 的容量,并且在添加新元素之前,将现有元素复制到新数组中。”

    【讨论】:

    • List.AddRange 将 IEnumerable 作为参数。这不是要一个接一个地处理每个字节吗? (而不是作为一个块)
    • 不,它会将其解释为 ICollection 并执行与 memcpy 一样快的 Array.Copy(它可能在后台使用 memcpy)。
    • @Asik,AddRange 结合 Jon 的答案中的代码应该可以解决问题。非常感谢!
    猜你喜欢
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    • 2012-11-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    相关资源
    最近更新 更多