2013-07-17 3 views
3

Каков наиболее эффективный способ перемещения коллекции/IEnumeration в C#. У меня есть список, который содержит почти 1100 объектов. почти 10 из этих объектов, inturn содержат 1000 подобъектов (одного типа). Переход к этому списку занимает почти 5-6 секунд. Вот мой код:Самый эффективный способ работы с IEnumerable

foreach (Parameter par in this.AllParameters) //this.AllParameters is Generic.List type 
{ 
    foreach (Parameter subPar in par.WrappedSubParameters) 
    { 
     subPar.IsSelected = false; 
    } 
    par.IsSelected = false; 
} 

Есть ли способ оптимизировать этот код, чтобы он был достаточно быстрым, не принимая 5-6 секунд?

+5

Я предлагаю вам сначала запустить [профилировщик] (http://stackoverflow.com/q/3927/87698) по вашему коду. Время может быть потеряно в свойстве 'AllParameters', в свойстве' WrappedSubParameters', в установщике 'IsSelected', в одном из счетчиков и т. Д. (О, и если у вас есть время, [серия Эрика Липперта об общем бенчмаркинге ошибки] (http://tech.pro/blog/1293/c-performance-benchmark-mistakes-part-one) стоит прочитать.) – Heinzi

+0

Я бы не ожидал, что примерно один миллион пишет, как это, взять 5 -6 секунд. Вы синхронизированы в сборке отладки? В релизе сборки вне VS, я бы ожидал, что это будет немного быстрее, чем в большинстве систем, если только что-то не происходит, например, 'IsSelected' является привязанным к данным и т. Д. –

+0

Да @ReedCopsey, IsSelected связан с свойство выделения DataGrid. Может ли это быть причиной цикла времени? – Irfan

ответ

4

Петли, как написано, скорее всего являются одним из самых быстрых вариантов.

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

Parallel.ForEach(this.AllParameters, par => 
{ 
    foreach (Parameter subPar in par.WrappedSubParameters) 
    { 
     subPar.IsSelected = false; 
    } 
    par.IsSelected = false; 
}); 

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


Другой потенциальной проблемой - если ваши IsSelected свойства связаны с контролем с помощью Data Binding, ваш пользовательский интерфейс будет потенциально обновляя постоянно, что может объяснить очень медленные времена обновления. Это может привести к тому, что распараллеливание не будет иметь реального эффекта, так как шея бутылки не будет этими петлями, а скорее связывает UI.

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

+0

Я уже пробовал это решение, но в моей ситуации он не добавил никакой разницы. Я использую компьютер x64 с Windows 7 – Irfan

+0

И теперь, ради эксперимента, я снова попробовал этот код, и каким-то образом моя программа переходит в не отвечающее состояние :( – Irfan

+1

@Irfan Я думаю, что проблема связана с данными. Используете ли вы WPF, WinForms, приложение для Windows Store и т. Д.? –

1

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

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

В противном случае не устанавливайте фактические свойства, просто устанавливайте поля, а после итерации вы можете уведомить пользовательский интерфейс.

Смежные вопросы