Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 哪个更快:清除集合还是实例化新集合_.net_Performance_List_Optimization_Collections - Fatal编程技术网

.net 哪个更快:清除集合还是实例化新集合

.net 哪个更快:清除集合还是实例化新集合,.net,performance,list,optimization,collections,.net,Performance,List,Optimization,Collections,我的代码中有一些通用列表,它们有几十个或几百个元素。 有时我需要用其他对象重新填充这个列表,所以问题是:调用Clear()方法或创建一个新列表()?虽然这可能会令人沮丧,但答案确实是这不重要。两者之间的时间差将非常小,可能不会对应用程序产生任何影响。做能让代码更清晰、更易懂的事情,尽量不要为微优化编程。如果对象是值类型,我会使用Clear()来减少未来的内存分配。否则,这两种方法几乎相同 调用Clear() 这是不可能回答的。这实际上取决于很多因素,包括收藏存在的时间 这里的最佳选择是: 分析应

我的代码中有一些通用列表,它们有几十个或几百个元素。
有时我需要用其他对象重新填充这个列表,所以问题是:调用
Clear()
方法或创建一个
新列表()

虽然这可能会令人沮丧,但答案确实是这不重要。两者之间的时间差将非常小,可能不会对应用程序产生任何影响。做能让代码更清晰、更易懂的事情,尽量不要为微优化编程。

如果对象是值类型,我会使用Clear()来减少未来的内存分配。否则,这两种方法几乎相同

调用
Clear()

这是不可能回答的。这实际上取决于很多因素,包括收藏存在的时间

这里的最佳选择是:

  • 分析应用程序,看看这是否真的很重要。它很可能不会产生任何明显的区别,在这种情况下,我会使用最有意义的方法来看待这个物体

  • 如果有关系,编写两组代码,并测量速度差异(如果有)

  • 从实际角度来看,调用
    Clear()
    实际上不会减少内存(由
    列表本身使用),因为它不会收缩列表的容量,只会消除其中包含的值。创建一个新的
    列表
    将导致分配一个新列表,这将随着增长而导致更多的分配

    但是,这并不意味着它会更慢—在许多情况下,重新分配会更快,因为您不太可能将大型阵列升级到更高的垃圾收集代,这反过来又可以使GC进程更快


    如果不知道您的确切场景并在探查器中进行测量,就无法知道在您的场景中哪一个更好。

    这将取决于许多因素,从长远来看,在您的程序中可能不重要(足以计算)

    从msdn
    .Clear()
    是一个O(n)操作

    初始化一个新实例将有它自己的开销(如果保持集合的长度不变,则会有一个O(n)操作:即n
    Add()
    calls)

    实际上,测试这一点的唯一方法是在你的程序中设置一些秒表,如果你真的认为值得的话,看看效果如何。极有可能;这不值得

    我的想法是,如果您已经创建了一个集合,
    Clear()
    it,这就是为什么首先会有一个
    Clear()
    方法。

    Clear()
    将删除所有元素,并保持现有容量,而创建一个新列表将至少需要从托管堆中分配一次(如果初始容量较小,可能会添加更多项)

    • 如果您有大量项目,并且每次迭代的项目数量大致相同,那么使用
      Clear
      可能会稍微快一点

    • 如果您在一次迭代中有非常多的项目,那么在后续迭代中的项目数量要小得多,那么使用
      Clear
      可能成本更高,因为您将在内存中保留一个容量不必要的列表

    当然,在许多(大多数?)场景中,差异可以忽略不计。

    我已经运行了以下测试:

    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;
    }
    
    private static void Main(字符串[]args)
    {
    int defaultN=1000;
    秒表sw=新秒表();
    while(true)
    {
    Console.WriteLine(“输入测试元素编号:”);
    int n;
    如果(!int.TryParse(Console.ReadLine(),out n))n=defaultN;
    n=n;
    WriteLine($“使用{n}个元素进行测试”);
    List=Enumerable.Repeat(新对象(),n).ToList();
    sw.Start();
    清除(列表);
    sw.Stop();
    Console.WriteLine(“清除:{0}ms”,sw.ElapsedTicks/10000D);
    GC.Collect();
    GC.WaitForPendingFinalizers();
    List list2=Enumerable.Repeat(new object(),n).ToList();
    sw.Restart();
    重新初始化(列表2);
    sw.Stop();
    Console.WriteLine(“重新初始化:{0}ms”,sw.ElapsedTicks/10000D);
    GC.Collect();
    GC.WaitForPendingFinalizers();
    List list3=Enumerable.Repeat(新对象(),n).ToList();
    sw.Restart();
    重新初始化并收集(列表3);
    sw.Stop();
    WriteLine(“重新初始化并收集:{0}ms”,sw.ElapsedTicks/10000D);
    Console.WriteLine(“=”);
    }
    }
    专用静态列表清除(列表)
    {
    list.Clear();
    退货清单;
    }
    私有静态列表重新初始化(列表)=>new List();
    私有静态列表重新初始化并收集(列表列表)
    {
    列表=新列表();
    GC.Collect();
    GC.WaitForPendingFinalizers();
    退货清单;
    }
    
    我的结论基于我的普通core i3处理器的结果:

    如果有数千个元素,最好清除列表。它速度快,内存效率高

    如果收集有超过100000个元素,则重新初始化会变得更吸引人。如果在分析之后您认为这里存在瓶颈,请使用它。重新初始化将非常快,但正如第三种方法测试所示,未来的垃圾收集将与清理列表一样慢


    简而言之,答案是:如果你没有分析你的应用程序,请使用
    Clear
    。重用对象是好的。如果你这样做了,你已经知道该怎么做了。

    也许我在这里做了一些根本错误的事情,但在用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);
    
    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);
    
    series.Clear();