Тестирование производительности ArrayList в C # - PullRequest
1 голос
/ 23 октября 2011

Я хочу провести тест производительности, показывающий, как быстро 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, намного больше, чем время, которое занимает Словарь. Почему это происходит?

Ответы [ 2 ]

4 голосов
/ 23 октября 2011

Ну, я бы предложил:

  • Не используйте файлы для получения ввода. Зачем вводить IO в систему?
  • Вместо того, чтобы многократно останавливать и запускать секундомер, просто вставьте множество строк в ArrayList, ничего не делая. Время, что большой цикл за один раз.

Что касается того, почему Dictionary<,> дешевле - вы не показывали никакого кода, но в основном ваш код вставки должен будет копировать все содержимое ArrayList при каждой вставке. ArrayList поддерживает массив для хранения содержимого списка. Обычно массив больше, чем список - когда вы добавляете элемент в конце, можно просто назначить новое значение в правый бит массива. Если вы вставите его в другое место, он должен скопировать элементы массива, чтобы «освободить место» для нового элемента.

Вы найдете это намного быстрее, добавив в конце. Dictionary<,> использует совершенно другую структуру данных; в некоторых точках его размер должен изменяться, но в целом он будет иметь очень разные характеристики.

(Я бы посоветовал вам использовать List<T> вместо ArrayList для начала, и если вы хотите, чтобы коллекцию можно было вставлять в начале несколько раз, рассмотрите LinkedList<T> - или, возможно, очередь или стек, в зависимости от на то, что вы хотите сделать с этим позже.)

1 голос
/ 23 октября 2011

Слишком много сложного. Прочитайте файл "обычно" в списке, добавляя в конце, а затем сравните тест, добавив первый список ко второму. В противном случае вы пытаетесь сравнить слишком много мелких действий, и у вас возникают проблемы с точностью.

Какой-то код

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 вы можете Start, Stop, а затем Start снова, и это будет продолжать сохранять время. Чтобы сбросить его, есть другой метод, Restart.

Как другие, вероятно, предложили:

  • Используйте List<string> вместо ArrayList (скорость та же, но List<string> безопасна для типа)
  • В общем, если вам нужно только вставить элементы в начало списков, вставьте их в хвост (намного быстрее) и «переверните» индекс (поэтому индекс 0 - это индекс Count - 1, 1 - Count - 2 и т. Д.). Списки не "сделаны" для вставки "в середине" или "сверху". Они сделаны для «добавить последний».
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...