我拼命想要找到一种更快的方法来创建一个没有其中任何项目的数组,而不是创建这些对象的列表并删除该项目。
原因是我的阵列平均有5个项目,少了很多次,并且创建一个列表只是为了删除我不再想要的一个项目,对我来说似乎太过分了。
由于我在一段时间后编写了我自己的探查器,我决定将这种方法和我想到的另一种方法放在一个测试中,结果很重要。
int[] a1 = new int[] { 1, 2, 3 };
方法1(创建对象列表并删除第2项):
Profiler.Start("Method 1");
List<int> a2 = new List<int>(a1);
a2.RemoveAt(1);
Profiler.Stop("Method 1");
方法2(创建一个大小相同但只有一个的数组,并删除第二个项目):
Profiler.Start("Method 2");
int[] a3 = new int[a1.Length - 1];
int l = 0;
for (int i = 0; i < a1.Length; i++) if (a1[i] != 2) { a3[l] = a1[i]; l++; }
Profiler.Stop("Method 2");
Profiler结果:
http://i.stack.imgur.com/al8i6.png
问题 为什么性能差异如此显着?
我从未真正花时间研究数组和列表之间的差异。
答案 0 :(得分:0)
似乎开销来自列表内容的初始化,而不是来自List.RemoveAt()
的调用。
换句话说,行List<int> a2 = new List<int>(a1);
占主导地位。
这里有一些代码试图消除List.RemoveAt()
和Array.Copy()
所花费的时间。
我的电脑上发布版本的结果是:
LIST Elapsed: 00:00:00.4724841
ARRAY Elapsed: 00:00:00.4670488
LIST Elapsed: 00:00:00.4714016
ARRAY Elapsed: 00:00:00.4675552
LIST Elapsed: 00:00:00.4703538
ARRAY Elapsed: 00:00:00.4698310
显示时间非常相似。
测试程序是:
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace Demo
{
public static class Program
{
public static void Main()
{
int[] a1 = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
int trials = 3;
int iterations = 10000000;
Stopwatch sw = new Stopwatch();
for (int i = 0; i < trials; ++i)
{
for (int j = 0; j < iterations; ++j)
{
List<int> a2 = new List<int>(a1);
sw.Start();
a2.RemoveAt(1);
sw.Stop();
}
Console.WriteLine("LIST Elapsed: " + sw.Elapsed);
sw.Reset();
for (int j = 0; j < iterations; ++j)
{
int[] a3 = new int[a1.Length - 1];
int l = 0;
sw.Start();
for (int k = 0; k < a1.Length; k++)
{
if (a1[k] != 2)
{
a3[l] = a1[k];
l++;
}
}
sw.Stop();
}
Console.WriteLine("ARRAY Elapsed: " + sw.Elapsed);
sw.Reset();
}
}
}
}