1. ホーム
  2. .net

[解決済み】配列とリストの性能比較

2022-04-06 06:42:26

質問

例えば、整数のリスト/配列が必要で、それを頻繁に、つまり非常に頻繁に反復する必要があるとします。理由は様々ですが、大量処理の最内周ループの中心にあるとします。

一般的には、サイズの柔軟性からリスト(List)を使うことを選択することになるでしょう。その上、msdnのドキュメントでは、Listは内部で配列を使っているので、同じように高速に動作するはずだと主張しています(Reflectorでざっと見て確認しました)。ただし、多少のオーバーヘッドが発生します。

リストで6M回繰り返し処理すると、配列と同じ時間がかかるのでしょうか?

解決方法は?

とても簡単に測定できるのですが・・・。

少数のタイトループ処理コードにおいて 長さが一定であることが分かっている場合 私は、このような微小な最適化のために配列を使用します。 僅かに より速く もし しかし、IRCでは、それは配列のデータの種類に依存すると信じています。しかし、あなたが 必要 を使用し、シンプルに保つことです。 List<T> などです。

もちろん、これはすべてのデータを読み込む場合にのみ適用されます。キーベースのルックアップにはディクショナリーを使用したほうが早いでしょう。

以下は、"int" を使った結果です(2番目の数字は、すべて同じ作業をしたことを確認するためのチェックサムです)。

(バグ修正のため編集)

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();
    }
}