Оптимизация кода c#, вложенного в цикл, с использованием параллельного

#c# #loops #memory #parallel-processing

Вопрос:

Мне нужно оптимизировать приведенный ниже код, чтобы он мог выполняться быстрее, используя больше памяти или параллельно, в настоящее время для завершения одной записи в Windows 10 64 бит, 16 ГБ ОЗУ ПК требуется 2 минуты

  1. длина массива списка data1 = 1000
  2. длина массива списка данных 2 = 100000
  3. длина массива списка данных 3 = 100
 for (int d1 = 0; d1 lt; data1.Count; d1  ) {  if (data1[d1].status == 'UNMATCHED')  {  for (int d2 = 0; d2 lt; data2.Count; d2  )  {  if (data2[d2].status == 'UNMATCHED')  {  vMatched = false;  for (int d3 = 0; d3 lt; data3.Count; d3  )  {  if (data3[d3].rule == "rule1")  {  if (data1[d1].value == data2[d2].value)  {  data1[d1].status = 'MATCHED';  data1[d2].status = 'MATCHED';  vMatched = true;  break;  }   }  else if (data3[d3].rule == "rule2")  {  ...  }  else if (data3[d3].rule == "rule100")  {  ...  }    }  if (vMatched)  break;  }  }  } }  

Комментарии:

1. «в настоящее время для завершения одной записи в 64 — разрядном ПК с Windows 10, 16 ГБ оперативной памяти требуется 2 минуты» — не уверен, что это означает… что такое рекорд?

Ответ №1:

Прежде всего, для любого вида программирования, ориентированного на производительность, избегайте использования строк, вместо этого используйте более подходящие типы, такие как enum или bools. Еще одна рекомендация-профилировать свой код, чтобы вы знали, какие части на самом деле требуют времени.

В данном примере представлено только одно правило, поэтому цикл data3 можно устранить, сначала проверив, существует ли это правило, и только затем приступая к сопоставлению.

Это сопоставление между элементами в data1 и data2 по существу объединяет несопоставимые элементы с одинаковым значением. Всякий раз, когда возникают подобные проблемы, стандартным решением является какая-то структура поиска, например словарь, чтобы получить лучшее, чем линейное время поиска. Например

 var data2Dictionary = data2.ToDictionary(d =gt; Tuple.Create(d.value, d.status), d =gt; d);  

Это должно позволить вам значительно сократить время поиска товара с определенным значением и статусом. Имейте в виду, что приведенный выше код будет выдан в случае, если несколько элементов имеют одинаковое значение и статус, и что ключ словаря не будет обновлен, если элемент изменит значение или статус.

Комментарии:

1. Спасибо, я попробую использовать опцию словаря и обновлю отзыв

Ответ №2:

Вы можете не начинать каждый раз 2-й цикл с 0. Сохраняя последний индекс с «НЕПРЕВЗОЙДЕННЫМ» внутри data2.

Это должно снизить сложность.

В худшем случае:

Сейчас 1000 * 100000 * 100 итерации: 10000000000

Новые (1000 100000) * 100 итераций: 10100000