.net 哪个更快:清除集合或实例化新的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10901020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Which is faster: clear collection or instantiate new
提问by Mrimsh
I have some number of generic lists in my code, that have tens or hundreds elements.
Sometimes I need to refill this lists with other objects, so question is: what will be faster, to call Clear()method or creating a new List<T>()?
我的代码中有一些通用列表,其中包含数十或数百个元素。有时我需要用其他对象重新填充这个列表,所以问题是:调用Clear()方法或创建new List<T>()?
采纳答案by Reed Copsey
what will be faster, to call
Clear()method or creating a `new List()?
调用
Clear()方法或创建`new List()会更快吗?
This is impossible to answer. It really depends on a lot of factors, including how long the collection has existed.
这是不可能回答的。这真的取决于很多因素,包括收藏品存在的时间。
The best option here would be to:
这里最好的选择是:
Profile the application, and see if this really matters. It likely won't make any perceptible difference, in which case, I'd use the method that makes the most sense in terms of how you think of this object.
If it does matter, write both sets of code, and measure the difference in speed (if any).
分析应用程序,看看这是否真的很重要。它可能不会产生任何可察觉的差异,在这种情况下,我会使用对您如何看待这个对象最有意义的方法。
如果确实重要,请编写两组代码,并测量速度差异(如果有)。
From a practical perspective, calling Clear()will not actually reduce the memory (used by the List<T>itself), as it doesn't shrink the list's capacity, only eliminates the values contained within it. Creating a new List<T>will cause a new list to be allocated, which will in turn cause more allocations with growth.
从实际的角度来看,调用Clear()实际上不会减少内存(由List<T>自身使用),因为它不会缩小列表的容量,只会消除其中包含的值。创建一个新的List<T>列表会导致分配一个新的列表,这反过来又会导致更多的分配随着增长而增加。
This, however, does not mean that it will be slower - in many cases, reallocating will be fasteras you're less likely to promote the large arrays into higher garbage collection generations, which in turn can keep the GC process much faster.
然而,这并不意味着它会变慢 - 在许多情况下,重新分配会更快,因为您不太可能将大型数组提升到更高的垃圾收集代,这反过来可以使 GC 过程更快。
Without knowing your exact scenario and measuringin a profiler, there is no way to know which is better in your scenario.
不知道您的具体情况,并测量在探查,也没有办法知道这是您的方案更好。
回答by astef
I've run this test:
我已经运行了这个测试:
private static void Main(string[] args)
{
int defaultN = 1000;
Stopwatch sw = new Stopwatch();
while (true)
{
Console.WriteLine("Enter test elements number:");
int n;
if (!int.TryParse(Console.ReadLine(), out n)) n = defaultN;
else defaultN = n;
Console.WriteLine($"Test with {n} elements");
List<object> list = Enumerable.Repeat(new object(), n).ToList();
sw.Start();
Clear(list);
sw.Stop();
Console.WriteLine("Clear: {0} ms", sw.ElapsedTicks / 10000D);
GC.Collect();
GC.WaitForPendingFinalizers();
List<object> list2 = Enumerable.Repeat(new object(), n).ToList();
sw.Restart();
Reinitialize(list2);
sw.Stop();
Console.WriteLine("Reinitialize: {0} ms", sw.ElapsedTicks / 10000D);
GC.Collect();
GC.WaitForPendingFinalizers();
List<object> list3 = Enumerable.Repeat(new object(), n).ToList();
sw.Restart();
ReinitializeAndCollect(list3);
sw.Stop();
Console.WriteLine("ReinitializeAndCollect: {0} ms", sw.ElapsedTicks / 10000D);
Console.WriteLine("===");
}
}
private static List<object> Clear(List<object> list)
{
list.Clear();
return list;
}
private static List<object> Reinitialize(List<object> list) => new List<object>();
private static List<object> ReinitializeAndCollect(List<object> list)
{
list = new List<object>();
GC.Collect();
GC.WaitForPendingFinalizers();
return list;
}
My conclusion based on a results of my ordinary core i3 processor:
我的结论基于我的普通核心 i3 处理器的结果:
In case of thousands of elements - it is better to clear list. It is fast and memory efficient.
如果有数千个元素 - 最好清除列表。它速度快,内存效率高。
If collection has more than 100 000 elements - reinitializing becomes more attractive. If after profiling you think that there is a bottleneck here, use it. Re-initialization will be very fast, but as third method test shows, future garbage collecting will be about as slow as just clearing the list.
如果集合有超过 100 000 个元素 - 重新初始化变得更有吸引力。如果在分析之后您认为这里存在瓶颈,请使用它。重新初始化会非常快,但正如第三种方法测试所示,未来的垃圾收集将与清除列表一样慢。
So short answer is: if you didn't profiled your application, use Clear. Reusing objects is good. If you did - you already know what to do.
简短的回答是:如果您没有分析您的应用程序,请使用Clear. 重用对象很好。如果你这样做了 - 你已经知道该怎么做了。
回答by NominSim
This is going to depend on a lot of factors, and in the long run, it probably will not matter (enough to count) in your program.
这将取决于很多因素,从长远来看,这在您的程序中可能无关紧要(足以计数)。
From the msdn docs.Clear()is a O(n) operation.
从 msdn docs.Clear()是一个 O(n) 操作。
Initializing a new instance will have its own overhead as well as (if you keep the collection the same length, a O(n) operation: i.e. n Add()calls).
初始化一个新实例将有它自己的开销以及(如果你保持集合的长度相同,一个 O(n) 操作:即 n 次Add()调用)。
Really the only way to test this is to set up some stopwatches in your program and see what the effect is if you really think it is worth it. In all likelihood; it's not worth it.
真正测试这一点的唯一方法是在您的程序中设置一些秒表,如果您真的认为值得,看看效果如何。在所有的可能性; 这不值得。
My thoughts would be that if you've already created a collection, Clear()it, that's why there is a Clear()method in the first place.
我的想法是,如果您已经创建了一个集合,Clear()这就是为什么首先要有一个Clear()方法。
回答by Chris Shain
While this may be frustrating, the answer really is that it shouldn't matter. The time difference between the two is going to be so small that it probably won't make any difference to your application. Do what leads to cleaner, more understandable code, and try not to program for micro-optimizations.
虽然这可能令人沮丧,但答案确实是它应该无关紧要。两者之间的时间差非常小,可能不会对您的应用程序产生任何影响。做什么会导致代码更清晰、更易于理解,并尽量不要为微优化而编程。
回答by hug
Maybe I'm doing something fundamentally wrong here but while developing an ASP.NET application in C# I'm encountering quite a difference when using Clear() vs. new. I'm creating a statistics page with charts, which have data series. For each chart I have a section where I do this:
也许我在这里做了一些根本性的错误,但是在 C# 中开发 ASP.NET 应用程序时,我在使用 Clear() 和 new 时遇到了很大的不同。我正在创建一个带有图表的统计页面,其中包含数据系列。对于每个图表,我都有一个部分来执行此操作:
chart = new ChartistChart() { Title = "My fancy chart" };
series = new List<ChartistMetaValue>();
*some code for getting the statistics*
chart.Series.Add(series);
chartistLineCharts.Add(chart);
then another chart follows.
然后是另一个图表。
chart = new ChartistChart() { Title = "My second fancy chart" };
series = new List<ChartistMetaValue>();
*some code for getting the statistics*
chart.Series.Add(series);
chartistLineCharts.Add(chart);
This works just fine with seriesbeing reallocated with new, but when I do
这series在重新分配new时工作得很好,但是当我这样做时
series.Clear();
instead I actually clear the entry inside chart.Seriesand chartistLineChartsso the statistics page ends up retrieving only the last chart's series. I assume there is some link, like a memory pointer, here and this is a different issue than what is originally discussed, but this is at least a reason to pick newover Clear(). Perhaps there is a way to avoid it though.
相反,我实际上清除了里面的条目chart.Series,chartistLineCharts因此统计页面最终只检索最后一个图表的系列。我认为有一些链接,就像一个内存指针,在这里,这是一个不同的问题比最初被讨论,但是这至少是一个理由选择new了Clear()。不过,也许有办法避免它。
回答by Michal Dobrodenka
I've made several tests for myself. Results (speed) are:
我为自己做了几次测试。结果(速度)是:
- for small lists - eg 3 items, its faster to create new lists, but the difference is not big
- for 10 or more items on average it is better to clear lists. For value types much better (eg 3-4 times), for value times like 20% better.
- 对于小列表 - 例如 3 个项目,创建新列表的速度更快,但差异不大
- 对于平均 10 个或更多项目,最好清除列表。对于值类型要好得多(例如 3-4 次),对于值时间要好 20%。
But in the end, it's better to profile application and find bottlenecks for whole application.
但最终,最好对应用程序进行概要分析并找到整个应用程序的瓶颈。
回答by Joe
Clear()will remove all elements, and maintain the existing capacity, whereas creating a new List will need at least one allocation from the managed heap (possibly more as items are added if the initial capacity is small).
Clear()将删除所有元素,并保持现有容量,而创建一个新的 List 将需要从托管堆中至少分配一次(如果初始容量很小,可能会随着项目的增加而分配更多)。
If you have a large number of items, and the number of items is roughly the same on each iteration, then using
Clearis potentially slightly faster.If you have an exceptionally large number of items on one iteration, then a much smaller number on subsequent iterations, then using
Clearis potentially more costly, because you'll be keeping in memory a list with an unnecessarily large capacity.
如果您有大量项目,并且每次迭代的项目数量大致相同,则 using
Clear可能会稍微快一些。如果您在一次迭代中有非常多的项目,那么在后续迭代中的项目数量要少得多,那么使用
Clear可能会更昂贵,因为您将在内存中保留一个容量过大的列表。
Of course, in many (most?) scenarios the difference will be negligible.
当然,在许多(大多数?)场景中,差异可以忽略不计。
回答by alexm
If your objects are value types I'd use Clear() to reduce memory futureallocations. Otherwise both approaches are almost identical.
如果您的对象是值类型,我会使用 Clear() 来减少未来的内存分配。否则两种方法几乎相同。

