#c# #.net #list #optimization #collections
#c# #.net #Список #оптимизация #Коллекции
Вопрос:
В настоящее время я работаю с приложением, которое будет выполнять следующее.
// Initialize a list:
myList = new List<aPoint>;
while(WeHaveMoreData)
myList->Add(ReturnNext1000Points());
У меня нет способа узнать общий размер списка с самого начала. Из того, что я прочитал, List<>
это лучший способ обрабатывать такое количество поступающих данных (может быть более 500 тыс. записей).
Мне интересно, должен ли я обрабатывать capicity списка (присвоить ему начальные значения или увеличить ограничение, если это необходимо)?
Как мне подойти к оптимизации такой процедуры?
Комментарии:
1. Чтобы добавить к вопросу, я работаю в рамках ограничений .net 2.0.
Ответ №1:
Если у вас есть приблизительное значение общего количества записей, вы могли бы установить емкость списка, в противном случае оставьте его расти. Он довольно оптимизирован, просто убедитесь, что у вас не заканчивается память. Другой подход заключается в использовании отложенного итератора, который не будет загружать весь список в память:
public IEnumerable<aPoint> GetPoints()
{
while(WeHaveMoreData)
{
yield return new aPoint();
}
}
Только после того, как вы начнете итерацию, записи начнут извлекаться одна за другой и немедленно освобождаться:
foreach (var point in GetPoints())
{
/// TODO: do something with the point
}
Комментарии:
1. Это было бы идеальным решением, к сожалению, я программирую на VC / 2.0, никаких дополнительных операций, а «GetNext1000» — это неуправляемый вызов функции C, извлекающий данные из Shmem
2. @greggorob64, почему тогда ваш вопрос помечен C #? Из-за этого тега я предположил, что это может быть приемлемым языком для вас.
3. Вы правы. Если я отмечу это как C , вопросы редко рассматриваются. Допустимым ограничением, которое я мог бы наложить на вопрос, является использование C # 2.0. Языки не расходятся (настолько сильно) до этого момента.
4. @greggorob64: Когда вы говорите об оптимизации на этом уровне, различные языковые механизмы — особенно управление памятью — и оптимизация компилятора сильно расходятся. Изменение тегов вопроса, чтобы его было видно больше, может привлечь больше просмотров, но не даст вам достаточно хорошего ответа.
5. Это справедливое замечание, но оно не игровое. Оптимизация кучи на любых языках clr не изменится достаточно радикально, чтобы гарантировать это. Решение было бы допустимо для любого из них.
Ответ №2:
Первое правило: преждевременная оптимизация — корень всего зла. Если производительность не является проблемой, оставьте все как есть. При этом вам следует попытаться установить начальный размер списка равным примерно AverageExpectedSize/0.7
.
Ответ №3:
Я также думаю, что вы не сможете его сильно оптимизировать.. Я думаю, вы могли бы добиться немного большего в некоторых конкретных случаях, поэтому у меня вопрос — что вы делаете с данными впоследствии? Также — вы хотите оптимизировать память или скорость?
Типичная реализация списка каждый раз увеличивает емкость в 2 раза, поэтому, возможно, вы могли бы сэкономить немного места, имея List<aPoint[]>
, в котором было бы намного меньше элементов, поэтому было бы менее вероятно, что у вас есть несколько 100 КБ свободной емкости. Но это имело бы значение только в том случае, если у вас вот-вот закончится память — в любом случае, вероятно, на сами данные тратится гораздо больше памяти..
Комментарии:
1. Данные анализируются и добавляются к визуализации данных. Построение гистограммы
2. Итак, вам действительно нужен весь набор точек сразу для анализа?
Ответ №4:
В общем, я бы сказал, что если вы не знаете количество элементов, скажем, в пределах / — 20%, то вам, вероятно, следует просто слепо добавлять в список, а не угадывать емкость.
Список отличается от массива, когда речь заходит о вопросах добавления при наличии емкости. Помните, что список удвоит свою емкость, как только вы превысите ее. Так, например, если ваш список имеет текущую емкость в 128 элементов, и вы добавляете элемент, который делает его 129 элементами, список изменит свою емкость до 256 элементов. Затем для следующих 128 добавлений вы вообще не изменяете размер списка. Как только вы дойдете до 257, оно удвоится до 512, и процесс повторится.
Таким образом, у вас будет O (log (n)) изменений размера вашего списка.