将数组的一部分添加到列表的内存高效方式

本文关键字:内存 高效 列表 方式 添加 数组 一部分 | 更新日期: 2023-09-27 18:22:30

假设我有以下变量:

byte[] fileData;
List<byte> bundleData;

我想取CCD_ 1的连续部分并将其添加到CCD_。我目前的方法基本如下:

int startIndex = 20, endIndex = 80;
byte[] transferredData = new byte[endIndex - startIndex];
Array.Copy(fileData, startIndex, transferredData, 0, transferredData.Length);
bundleData.AddRange(transferredData);

创建中间数组可以很好地工作,但它使用了看似不必要的副本。有没有任何方法可以在不使用冗余阵列的情况下直接添加数据?

作为参考,我在这个项目中使用.NET 2.0。

将数组的一部分添加到列表的内存高效方式

另一种(可能是有效的)方法是使用LINQ:

bundleData.AddRange(fileData.Skip(startIndex).Take(endIndex - startIndex));

列表<T>类本质上只是包装一个T数组,当数组已满时,它将被一个更大的T数组替换。将字节数组附加到List<字节>将字节直接复制到内部字节数组中。

然而,列表<T>类不公开内部数组,所以最好的选择可能是确保列表有足够的容量,不需要多次替换内部数组,然后逐个添加每个字节:

bundleData.Capacity += endIndex - startIndex + 1;
for (int i = startIndex; i <= endIndex; i++)
{
    bundleData.Add(fileData[i]);
}

您也可以使用AddRange进行实验,并提供字节数组的视图:

static IEnumerable<T> Range<T>(this T[] array, int offset, int count)
{
    for (int i = 0; i < count; i++)
    {
        yield return array[offset + i];
    }
}
bundleData.AddRange(fileData.Range(startIndex, endIndex - startIndex + 1));

如果您实际上不需要List<字节>例如,一个更好的选择可能是MemoryStream类:

内存流类

创建其后备存储为内存的流。

示例:

MemoryStream bundleData = new MemoryStream();
bundleData.Write(fileData, startIndex, endIndex - startIndex + 1);
List.AddRange方法实现如下。我将添加一些伪代码进行解释。
ICollection<T> is2 = collection as ICollection<T>;
if(is2!=null)
{
   //then use Array.Copy
}
else
{
 //Loop through GetEnumerator() and calls Insert()
}

因此,中间数组将是IMHO的最佳想法,因为数组实现了ICollection。希望这能有所帮助。