#c# #loops #memory #parallel-processing
Вопрос:
Мне нужно оптимизировать приведенный ниже код, чтобы он мог выполняться быстрее, используя больше памяти или параллельно, в настоящее время для завершения одной записи в Windows 10 64 бит, 16 ГБ ОЗУ ПК требуется 2 минуты
- длина массива списка data1 = 1000
- длина массива списка данных 2 = 100000
- длина массива списка данных 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