Да, вы можете go быстрее, потому что у вас уже есть HashSet
в руке. LINQ Intersect
использует универсальный c алгоритм , который по сути воссоздает HashSet
с нуля при каждом вызове. Вот более быстрый алгоритм:
/// <summary>Yields all the elements of first (including duplicates) that also
/// appear in second, in the order in which they appear in first.</summary>
public static IEnumerable<TSource> Intersect<TSource>(IEnumerable<TSource> first,
HashSet<TSource> second)
{
foreach (TSource element in first)
{
if (second.Contains(element)) yield return element;
}
}
Обновление: Вот параллельная версия вышеуказанной идеи:
var intersected = list.AsParallel().Where(x => hashset.Contains(x)).ToArray();
Я бы не ожидал это должно быть намного быстрее, если вообще, потому что рабочая нагрузка слишком гранулированная . Затраты на вызов лямбды 300 000 раз, вероятно, затмят любые преимущества параллелизма.
Кроме того, порядок результатов не будет сохранен, если только метод AsOrdered
PLINQ не будет добавлен в запрос, что вредит дальнейшему выполнению операции.