Эффективное создание списка <MyObject>с большим количеством элементов - PullRequest
1 голос
/ 15 декабря 2011

В моем коде мне иногда нужно создавать большие коллекции объектов.Обратите внимание, что мне нужны коллекции, а не массивы, потому что, возможно, мне понадобится добавить элементы позже.

Какой эффективный способ сделать это?

Предположим, что объекты довольно просты исоздается быстро с конструктором по умолчанию без параметров.Примерно так:

class MyObject
{
    private int a;

    public int A
    {
        get { return a; }
        set { a = value; }
    }
}

Конечно, я могу создать свою коллекцию так:

List<MyObject> list = new List<MyObject>(knownNumberOfItems);
for (int i = 0; i < knownNumberOfItems; i++)
    list.Add(new MyObject());

Но, может, есть лучший способ сделать то же самое?

Подведение итогов обсуждения:

  • Нет более быстрого способа сделать это для ссылочных типов.Вы можете получить некоторые улучшения производительности, используя типы значений.
  • Попробуйте выделить больше места на начальном этапе, чтобы уменьшить количество перераспределений при добавлении новых элементов позже.

Ответы [ 5 ]

2 голосов
/ 15 декабря 2011

Нет более быстрого способа, с которым я знаком.Я бы лично использовал фигурные скобки вокруг тела цикла for, но в качестве способа создания списка заданного размера, заполненного различными ссылками на новые объекты, вот и все.Важной частью является то, что вы указали размер списка для начала, поэтому эти Add вызовы не будут нуждаться в перераспределении чего-либо внутри.

Если вы собираетесь добавлять элементы позже, вы может хочет, конечно, немного увеличить размер.

Маловероятно, что это узкое место в вашей системе - и, как всегда, удобочитаемость должна быть вашей главной задачей (и нездесь не проблема, кроме предложенного мной изменения), когда производительность постоянно измеряется, но вызывает изменения только на низком уровне, когда проблема подтверждается измерениями.

1 голос
/ 15 декабря 2011

Подумайте о том, чтобы сделать ваш тип типом значения (struct), чтобы вам не нужно было выделять память для экземпляров и чтобы ваш список не фрагментировал память.После этого создайте список вроде:

var List = new MyList<MyObject>(Enumerable<MyObject>.Repeat(new MyObject(),
                                known_number_of_items));

Из его документации гарантированно будет работать O(n).однако это не будет работать со ссылочным типом (class), поскольку он будет вставлять один и тот же объект снова и снова.

1 голос
/ 15 декабря 2011

Я мог бы рассмотреть

LinkedList<T> list = ...

Операции добавления в связанные списки имеют постоянное время.

1 голос
/ 15 декабря 2011

Ваш путь довольно эффективен - создается массив с достаточным пространством для всех ваших элементов и списков. Добавление невероятно быстрое.

У вас проблемы с производительностью?

1 голос
/ 15 декабря 2011

Нет в .Net 2.0. Начиная с .Net 3.5, вы можете написать его немного короче, но скомпилированный результат будет в основном таким же.

...