1

ArrayList(System.Collections - C#) が最初に項目を挿入できる速さについてパフォーマンス テストを行いたいと考えています。

データ行を読み取るためのファイルを開き、ストップウォッチを設定し、項目を追加するための ArrayList も作成しました (次のように)。

Stopwatch watchTime = new Stopwatch();
Double totalTime = 0; 
using (StreamReader readText = new StreamReader("data.txt"))
{
    String line;
    Int32 counter = 0; 
    while ((line = readText.ReadLine()) != null)
    {
    }
}

カウンターを使用して、ArrayList に入力しているアイテムの数を追跡します。

while ループ内には、次のものがあります。

watchTime.Start();
theList.Insert(0, line);
watchTime.Stop();
Double time = watchTime.Elapsed.TotalMilliseconds;
totalTime = totalTime + time; 
Console.WriteLine(time);
watchTime.Reset();
++counter; 

これは、ArrayList の先頭にアイテムを挿入する速度を確認する正しい方法ですか??

まったく同じことを行う別のプログラムを作成しましたが、辞書を使用しています。驚いたことに、この ArrayList がアイテムを挿入するのにかかる時間は、Dictionary がかかる時間よりもはるかに長くなります。なぜこうなった?

4

2 に答える 2

4

さて、私はお勧めします:

  • ファイルを使用して入力を取得しないでください。システムに IO を導入する理由
  • ArrayListストップウォッチの停止と開始を繰り返す代わりに、他に何もせずにたくさんの行を に挿入します。一度に大きなループの時間を計ります。

安い理由についてDictionary<,>は、コードは表示されませんでしたが、基本的に挿入コードはArrayList挿入ごとにコンテンツ全体をコピーする必要があります。ArrayListリストの内容を保持する配列を維持します。通常、配列はリストよりも大きくなります。最後に要素を追加すると、新しい値を配列の右側のビットに割り当てることができます。他の場所に挿入する場合は、配列の要素をコピーして、新しい要素用の「スペースを空ける」必要があります。

最後に追加すると、はるかに速くなります。Dictionary<,>完全に異なるデータ構造を使用します。いくつかの点でサイズを変更する必要がありますが、一般的に非常に異なる特性を持っています。

(開始するList<T>代わりに使用することをお勧めしますArrayList。コレクションの開始時に繰り返し挿入できるコレクションが必要な場合は、LinkedList<T>後で何をしたいかによって、キューまたはスタックを検討してください。)

于 2011-10-23T07:05:32.337 に答える
1

複雑すぎる。最後にリストを追加して「通常どおり」ファイルを読み取り、最初のリストを2番目のリストに追加してベンチマークします。そうしないと、あまりにも多くの小さなアクションをベンチマークしようとすることになり、精度の問題が発生します。

いくつかのコード

ArrayList tempList = new ArrayList();

using (StreamReader readText = new StreamReader("data.txt"))
{
    String line;
    Int32 counter = 0; 
    while ((line = readText.ReadLine()) != null)
    {
        tempList.Add(line);
    }
}

ArrayList theList = new ArrayList();

Stopwatch watchTime = Stopwatch.StartNew();

foreach (string line in tempList)
{
    theList.Insert(0, line);
}

watchTime.Stop();

私はStopwatchあなたができることを追加しますStartStopそしてStart再び、それは時間を保ち続けます. リセットするには、別の方法がありRestartます。

他の人がおそらく示唆しているように:

  • List<string>代わりに使用しますArrayList(速度は同じですが、List<string>タイプ セーフです)
  • 一般に、リストの先頭にのみ要素を挿入する必要がある場合は、要素を末尾に挿入し (はるかに高速)、インデックスを「反転」します (つまり、 index0は index Count - 1、1 はCount - 2など)。リストは、「真ん中に」または「一番上に」挿入するために「作成」されていません。それらは「最後に追加」するために作られています。
于 2011-10-23T07:07:24.577 に答える