将项目部分复制到List的最佳方法
本文关键字:最佳 方法 List 项目部 复制 | 更新日期: 2023-09-27 18:08:03
假设您有两个数组,src
和dest
。dest
更大。您想要复制从src
到dest
开头的所有元素,并覆盖可能已经存在的任何元素。要做到这一点,我们可以使用Array.Copy(src, dest, src.Length)
,它比for循环更简洁、更有效。
现在,假设dest
变成List<T>
。从src
复制所有元素的最有效方法是什么?我知道列表是内部实现使用数组,所以如果我们能得到我们的手(禁止反射,当然),我们可以做一个Array.Copy
,这将是一个没有问题。
由于上述原因,我不是在寻找for循环,但如果这是唯一的方法,我想必须这样做。
编辑:我希望不用在手机上输入代码示例,但从大量错误的答案来看,我似乎不得不:
int[] src = { 1, 2, 3 };
var dest = new List<int>() { 4, 5, 6, 7 };
for (int i = 0; i < src.Length; i++)
{
dest[i] = src[i];
}
我正在寻找的将是上述逻辑等效,但具有Array.Copy.
要达到与Array.Copy
相同的结果,我将使用
var src = new int[] { 50, 51, 52, 53, 54, 55 };
var dest = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
dest.RemoveRange(0, src.Length);
dest.InsertRange(0, src);
// dest: [ 50, 51, 52, 53, 54, 55, 7, 8, 9, 10, 11, 12 ]
编辑:这种方法大约比Array.Copy
慢7倍,但是对于大型数组来说,比遍历数组快得多。如果源数组较小,则循环可能是最佳选择。
我想你在找这样的东西:
int[] desta = (int[]) typeof(List<int>)
.GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(dest);
Array.Copy(src, desta, src.Length)
为什么不能在src
数组上调用ToList()
,这将从int[]
创建List<int>
。小样本
int[] src = new int[] { 1,2,3,4,5,6,7,8,44,555,45,654};
List<int> dest = src.ToList();
你也可以做
int[] src = new int[] {1, 2, 3};
List<int> dest = new List<int>(src);
如果你的src是一个列表,另一个选择是使用ForEach定义在列表中,我相信性能类似于Array。复制
dest = new List<T>();
src.ForEach(item => dest.Add(item));
如果需要值复制,可以这样写:
src.ForEach(item => dest.Add(item.Clone()));
在这种情况下,只需要确保项目是iclonable。
刚刚将您的函数与Array.Copy()函数进行了比较。
//values used for the benchmark
int[] src = { 1, 2, 3 };
int[] destArray = { 4, 5, 6, 7 };
var destList = new List<int>() { 4, 5, 6, 7 };
//Array.Copy() test : avarage 1004 ms
for (int i = 0; i < 20000000; i++)
{
Array.Copy(src, destArray, src.Length);
}
//Your solution test : avarage 634 ms
for (int i = 0; i < 20000000; i++)
{
Copy(src, destList, src.Length);
}
public void Copy(int[] sourceArray, List<int> destinationList, int length)
{
for (int i = 0; i < length; i++)
{
destinationList[i] = sourceArray[i];
}
}
*这些结果是20次基准测试的平均值。