Darren Kopp answer :
var excluded = items1.Except(items2);
- The best solution in terms of performance.
(NB: this is true for at least regular LINQ, maybe LINQ to SQL changes things according to a blog post by Marco Russo . "Imagine that in the" worst case "Darren Kopp's method will return at least the speed of the Russian method even in LINQ to SQL) .
As a quick example, try this in LINQPad :
void Main() { Random rand = new Random(); int n = 100000; var randomSeq = Enumerable.Repeat(0, n).Select(i => rand.Next()); var randomFilter = Enumerable.Repeat(0, n).Select(i => rand.Next()); (from el1 in randomSeq where !(from el2 in randomFilter select el2).Contains(el1) select el1).Dump("Result"); randomSeq.Except(randomFilter).Dump("Result"); }
Try commenting on one of the two methods at a time and try performance for different n values.
My experience (on my Core 2 Duo laptop) seems to suggest:
n = 100. Method 1 takes about 0.05 seconds, Method 2 takes about 0.05 seconds n = 1,000. Method 1 takes about 0.6 seconds, Method 2 takes about 0.4 seconds n = 10,000. Method 1 takes about 2.5 seconds, Method 2 takes about 0.425 seconds n = 100,000. Method 1 takes about 20 seconds, Method 2 takes about 0.45 seconds n = 1,000,000. Method 1 takes about 3 minutes 25 seconds, Method 2 takes about 1.3 seconds
Method 2 (Darren Kopp's answer) is clearly faster.
The slowdown for method 2 for larger n is most likely due to the generation of random data (feel free to insert a DateTime diff to confirm this), while method 1 clearly has problems with algorithmic complexity (and just looking at you can see that it at least O (N ^ 2), since for each number in the first collection it is compared with the entire second collection).
Conclusion: Use Darren Kopp's answer to the LINQ 'Except' method