List A:
1, 2, 3, 4
List B:
2, 5
How to check if list A contains any value from list B?
e.g. someth
I write a faster method for it can make the small one to set. But I test it in some data that some time it's faster that Intersect but some time Intersect fast that my code.
public static bool Contain(List a, List b)
{
if (a.Count <= 10 && b.Count <= 10)
{
return a.Any(b.Contains);
}
if (a.Count > b.Count)
{
return Contain((IEnumerable) b, (IEnumerable) a);
}
return Contain((IEnumerable) a, (IEnumerable) b);
}
public static bool Contain(IEnumerable a, IEnumerable b)
{
HashSet j = new HashSet(a);
return b.Any(j.Contains);
}
The Intersect calls Set
that have not check the second size and this is the Intersect's code.
Set set = new Set(comparer);
foreach (TSource element in second) set.Add(element);
foreach (TSource element in first)
if (set.Remove(element)) yield return element;
The difference in two methods is my method use HashSet
and check the count and Intersect
use set
that is faster than HashSet
. We dont warry its performance.
The test :
static void Main(string[] args)
{
var a = Enumerable.Range(0, 100000);
var b = Enumerable.Range(10000000, 1000);
var t = new Stopwatch();
t.Start();
Repeat(()=> { Contain(a, b); });
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//490ms
var a1 = Enumerable.Range(0, 100000).ToList();
var a2 = b.ToList();
t.Restart();
Repeat(()=> { Contain(a1, a2); });
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//203ms
t.Restart();
Repeat(()=>{ a.Intersect(b).Any(); });
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//190ms
t.Restart();
Repeat(()=>{ b.Intersect(a).Any(); });
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//497ms
t.Restart();
a.Any(b.Contains);
t.Stop();
Console.WriteLine(t.ElapsedMilliseconds);//600ms
}
private static void Repeat(Action a)
{
for (int i = 0; i < 100; i++)
{
a();
}
}