Reputation: 30298
I have two List<Guid>()
s and I want to find GUID
values that are not in the second list.
How do I do this using LINQ
? I think LINQ
would be a more efficient approach than a foreach()
.
Upvotes: 0
Views: 1704
Reputation: 32248
I made a test, to compare the how much time different methods take to complete this task.
For the test, I used 2 List<Guid>
of 200 items each.
The second list contains ~1/10 of pseudo-random elements which are also in the first one.
I measured the time each method required to complete using a StopWatch()
.
Since
Except
,Where
andLookUp
are cached, the test has been restarted each time. It can however be useful to know that the cached Functions take only a fewTick
(1 ~ 7) to complete once initialized.
If the same query must be repeated multiple times, these Functions' feature can really make the difference.
This is how the two Lists are created:
static Random random = new Random();
// [...]
random.Next(0, 10);
List<Guid> guid1 = new List<Guid>(200);
List<Guid> guid2 = new List<Guid>(200);
int insertPoint = random.Next(0, 10);
for (int x = 0; x < 200; x++)
{
guid1.Add(Guid.NewGuid());
guid2.Add((x == insertPoint) ? guid1.Last() : Guid.NewGuid());
if (x > 9 && ((x % 10F) == 0.0F))
insertPoint = random.Next(x, x + 10);
}
These are the Functions tested:
List1 Except
List2:
var result1 = guid1.Except(guid2);
List1.Item Where
!= List2.Item
var result2 = guid1.Where(guid1 => guid2.All(g => g != guid1));
List1.Items FindAll
!= List2.Items
var result3 = guid1.FindAll(g1 => guid2.All(g2 => g2 != g1));
List1.Item LookUp Contains
(List2.Item)
var lookUpresult = guid1.ToLookup(g1 => guid2.Contains(g1));
var result4 = lookUpresult[false].ToList();
List1 Hashset GroupBy Contains
(List2 Hashset
)
var guidHS1 = new HashSet<Guid>(guid1);
var guidHS2 = new HashSet<Guid>(guid2);
var hsGroups = guid1.GroupBy(g => guidHS2.Contains(g));
var result5 = hsGroups.First().ToList();
ForEach
List1->Item ForEach
List2->Item (Item1 == Item2) => List3
List<Guid> guid3 = new List<Guid>();
bool found;
foreach (Guid guidtest in guid1) {
found = false;
foreach (Guid guidcompare in guid2) {
if (guidtest == guidcompare) {
found = true;
break;
}
}
if (!found) guid3.Add(guidtest);
}
These are the results of this test: (20 rounds)
Number of equal elements found: 181~184
EXCEPT => Time: 1724 ~ 4356 ticks
WHERE => Time: 3651 ~ 7360 ticks
FINDALL => Time: 3037 ~ 6472 ticks
LOOKUP => Time: 9406 ~ 16502 ticks
HASHSET GROUPBY => Time: 1773 ~ 3597 ticks
FOREACH => Time: 650 ~ 1529 ticks
Upvotes: 1
Reputation: 24187
For that you can use the LINQ Except()
extension method:
var result = list1.Except(list2);
Upvotes: 4