Radzhab
@Radzhab

Как ускорить процесс поиска совпадение в двух списках?

Есть два файла. Считываю из них оба значения в списки. Хочу взять уникальные значения из обоих списков, однако процесс поиска и сравнения идет очееень долго(строк в обоих списках ~300к). Подскажите как ускорить процесс поиска и сравнения*?
var lst1 = File.ReadAllLines(@ "D:\test\1.csv").ToList();
 var lst2 = File.ReadAllLines(@ "D:\\test\2.csv").ToList();

 var rez = lst2.Where(x => !MySequenceContains(lst1, x)).
 Select(q => string.Join(";", q)).ToList();

 }

 private bool MySequenceContains(List < string > x, string y) {
  bool contains = false;
  index++;
  label2.Text = index.ToString();
  foreach(var a in x) {
   // ToDo: tweak the string comparison as needed
   if (string.Compare(a.Split(';')[0], y.Split(';')[0], StringComparison.InvariantCultureIgnoreCase) == 0 &&
    string.Compare(a.Split(';')[14], y.Split(';')[14], StringComparison.InvariantCultureIgnoreCase) == 0) {
    contains = true;
    break;
   }
  }
  return contains;
 }
  • Вопрос задан
  • 393 просмотра
Пригласить эксперта
Ответы на вопрос 3
GavriKos
@GavriKos
Самое примитивное - делайте split один раз. По возможности - вообще от него избавьтесь.
Дальше - можно использовать в качестве первого списка hashset - по нему поиск очень быстрый. Но вот время на заполнение может портатите больше.
Еще из вариантов - удалять найденую строку из первого листа - чтобы он с каждым поиском становился все меньше. Черт его подойдет ли под вашу задачу (дубликаты там всякие), ну и List для такого удаления не очень подходит.
Ответ написан
Комментировать
Если значения - числа, то свести сравнение строк к сравнению чисел, будет быстрее.
Если все же значения - строки, то можно посчитать хэш каждой строки и затем их сравнивать.
Ну и пара ссылок:
programmers.stackexchange.com/questions/280361/lis...
stackoverflow.com/questions/3687836/what-is-the-mo...
Ответ написан
Комментировать
@JuniorNoobie
Сижу в поддержке, пишу мелкие проекты
Если уникальные и не важно из какого списка, то можно сделать так:
1) объединить два списка в один;
2) сгруппировать список по значению;
3) взять только те значения, у которых count() = 1.

В ORACLE это выглядело бы так:
SELECT str
FROM lst
GROUP BY str
HAVING count(*) = 1
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы