为啥性能测试显示我的代码列表比数组快得多? [复制]

Posted

技术标签:

【中文标题】为啥性能测试显示我的代码列表比数组快得多? [复制]【英文标题】:Why performance test shows me that lists are much faster than arrays with my code? [duplicate]为什么性能测试显示我的代码列表比数组快得多? [复制] 【发布时间】:2021-04-09 10:04:41 【问题描述】:
LIST FOR      00:00:00.0000980
LIST FOREACH  00:00:00.0000007
ARRAY FOR     00:00:00.0028450
ARRAY FOREACH 00:00:00.0051233

我总是用数组来做性能很重的事情,但列表似乎要快得多。

using System;
using System.Diagnostics;
using System.Collections.Generic;

public class Program

    public static void Main()
    
        var cron = NCrontab.Advanced.CrontabSchedule.Parse("0 0 1 1 * 2016",
            NCrontab.Advanced.Enumerations.CronStringFormat.WithYears);
        var date = new System.DateTime(year: 2016, month: 1, day: 1,
            hour: 0, minute: 0, second: 0);
        
        int[] testArray = new int[1000000];
        List<int> testList = new List<int>(1000000);
        
        var stopWatch = new Stopwatch();
        stopWatch.Start();
        for (int i = 0; i < testList.Count;i++)
        
            var s = 1;
        
        stopWatch.Stop();
        Console.WriteLine("LIST FOR      " + stopWatch.Elapsed);
        
        stopWatch = new Stopwatch();
        stopWatch.Start();
        foreach (int i in testList)
        
            var d = 1;
        
        stopWatch.Stop();
        Console.WriteLine("LIST FOREACH  " + stopWatch.Elapsed);
                
        stopWatch = new Stopwatch();
        stopWatch.Start();
        for (int i = 0; i < testArray.Length;i++)
        
            var f = 1;
        
        stopWatch.Stop();
        Console.WriteLine("ARRAY FOR     " + stopWatch.Elapsed);
        
        stopWatch = new Stopwatch();
        stopWatch.Start();
        foreach (int i in testArray)
        
            var h = 1;
        
        stopWatch.Stop();
        Console.WriteLine("ARRAY FOREACH " + stopWatch.Elapsed);
    

https://dotnetfiddle.net/RKWBJl

List 内部实现了 T[],只是它的灵活性和内部在容量结束时不断扩展。因为对于所有重要的操作,它在内部做数组操作,只是为动态扩展提供了方便。

我看不懂,但是对于繁重频繁的操作,我需要知道。

基本上,我正在尝试确定高 FPS 的最佳选择。

【问题讨论】:

在您的测试中,您不是从数组或列表中读取或写入值,而是仅检查计数/长度并分配执行不涉及列表/数组的操作。列表的计数始终为 0,因为没有项目添加到列表中。我已经获取了您的代码并更改了逻辑。检查此fiddle。您会看到在实际示例中数组比列表更快。也可以参考https://***.com/questions/454916/performance-of-arrays-vs-lists 不是不相关且具有误导性的重复项所指示的性能问题。但是问题不可重现,因为它不存在,正如@.user1672994 评论和@.KarlJohanSjögren 回答的那样。 感谢好友@user1672994,您的评论和小提琴很有帮助 @OlivierRogier 我投票赞成重新讨论这个问题,因为它似乎不是linked question 的副本。恕我直言,该问题应该以“不可重现或由拼写错误”为由关闭,因为所报告的性能差异只是测量有缺陷的结果。 Charlini 语句new List&lt;int&gt;(1000000) 创建了一个Capacity 为1,000,000 的列表,而不是Count 为1,000,000 的列表。您正在枚举一个空列表。 【参考方案1】:

这些测试没有可比性。

这将创建一个包含一百万个条目的数组。

int[] testArray = new int[1000000];

这会创建一个空列表,但在后台分配的内存最多可容纳一百万个条目(因此它不必调整其内部缓冲区的大小,直到达到一百万。

List<int> testList = new List<int>(1000000);

所以testArray.Length 在这里将是 1000000,testList.Count 将是 0(因为您没有向其中添加一百万个项目)。

在性能方面,还需要考虑很多其他事情,然后只循环这些值。例如,如果数组导致您需要调整其大小,则添加或删除项目可能会非常昂贵。

这里的第二件事是,您对这些事物进行基准测试的方式也不会真正可靠。如果您想做实际的基准测试,请查看https://benchmarkdotnet.org,它会正确执行此操作并处理诸如预热运行、内存分配、在不同框架版本上运行等事情。

【讨论】:

以上是关于为啥性能测试显示我的代码列表比数组快得多? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥用 C 复制文件比 C++ 快得多?

为啥列表理解比附加到列表要快得多?

为啥 KNN 比决策树快得多?

为啥在迭代 NumPy 数组时 Cython 比 Numba 慢得多?

为啥 memcmp 比 for 循环检查快得多?

为啥 MySQL JOIN 比 WHERE IN (子查询) 快得多