小编典典

数组与列表的性能

all

假设您需要一个需要经常迭代的整数列表/数组,我的意思是非常频繁。原因可能会有所不同,但可以说它是大容量处理的最内部循环的核心。

一般来说,由于大小的灵活性,人们会选择使用列表(List)。最重要的是,msdn 文档声称列表在内部使用了一个数组,并且应该同样快速地执行(快速浏览一下
Reflector 就证实了这一点)。然而,这涉及到一些开销。

有人真的测量过这个吗?在列表中迭代 6M 次是否会与数组花费相同的时间?


阅读 69

收藏
2022-06-06

共1个答案

小编典典

非常容易测量…

在我知道长度是固定* 的少数紧密循环处理代码中,我使用数组进行额外的微小优化; 如果 您使用索引器 / 用于表单,数组可能会 稍微
快一些 - 但 IIRC 认为这取决于数组中的数据类型。但是除非您 需要 进行微优化,否则请保持简单并使用等。
***List<T>

当然,这只适用于读取所有数据的情况;对于基于键的查找,字典会更快。

这是我使用“int”的结果(第二个数字是校验和,以验证它们都做了相同的工作):

(已编辑以修复错误)

List/for: 1971ms (589725196)
Array/for: 1864ms (589725196)
List/foreach: 3054ms (589725196)
Array/foreach: 1860ms (589725196)

基于测试台:

using System;
using System.Collections.Generic;
using System.Diagnostics;
static class Program
{
    static void Main()
    {
        List<int> list = new List<int>(6000000);
        Random rand = new Random(12345);
        for (int i = 0; i < 6000000; i++)
        {
            list.Add(rand.Next(5000));
        }
        int[] arr = list.ToArray();

        int chk = 0;
        Stopwatch watch = Stopwatch.StartNew();
        for (int rpt = 0; rpt < 100; rpt++)
        {
            int len = list.Count;
            for (int i = 0; i < len; i++)
            {
                chk += list[i];
            }
        }
        watch.Stop();
        Console.WriteLine("List/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk);

        chk = 0;
        watch = Stopwatch.StartNew();
        for (int rpt = 0; rpt < 100; rpt++)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                chk += arr[i];
            }
        }
        watch.Stop();
        Console.WriteLine("Array/for: {0}ms ({1})", watch.ElapsedMilliseconds, chk);

        chk = 0;
        watch = Stopwatch.StartNew();
        for (int rpt = 0; rpt < 100; rpt++)
        {
            foreach (int i in list)
            {
                chk += i;
            }
        }
        watch.Stop();
        Console.WriteLine("List/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk);

        chk = 0;
        watch = Stopwatch.StartNew();
        for (int rpt = 0; rpt < 100; rpt++)
        {
            foreach (int i in arr)
            {
                chk += i;
            }
        }
        watch.Stop();
        Console.WriteLine("Array/foreach: {0}ms ({1})", watch.ElapsedMilliseconds, chk);

        Console.ReadLine();
    }
}
2022-06-06