8
votes
\$\begingroup\$

I'm wondering about the difference between these two linq statements

bool overlap = GetMyListA().Intersect(GetMyListB()).Any(); // 1.

vs

bool overlap = GetMyListA().Any(i => GetMyListB().Contains(i)); // 2.

Will statement 2. call GetMyListB() for each item in ListA?

Which is more readable?

\$\endgroup\$

locked by Jamal Feb 7 '16 at 16:26

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. More info: help center.

Read more about locked posts here.

  • \$\begingroup\$ Both will yield the same result (assuming there are no side-effects in GetMyListA() or GetMyListB()). I'd say 1 is the most readable and 2 the most logical. \$\endgroup\$ – Jeff Mercado Jun 27 '12 at 15:10
  • \$\begingroup\$ Is there any difference in performance? Would 'GetMyListB()' be called multiple times? \$\endgroup\$ – Kim Jun 27 '12 at 15:18
  • 3
    \$\begingroup\$ Assuming you're working with lists, there would likely be a performance difference. Using Intersect() would utilize hash sets to determine uniqueness. The other code would perform linear searches through list B and would return on the first match (and yes, GetMyListB() will be called for each item in list A). \$\endgroup\$ – Jeff Mercado Jun 27 '12 at 15:40
  • 1
    \$\begingroup\$ It really depends on the linq provider and the types of the objects. This question would be better for stackoverflow though. \$\endgroup\$ – Bill Barry Jun 27 '12 at 16:56
  • \$\begingroup\$ A similar question of me: stackoverflow.com/questions/10110013/… Short answer: In LINQ-To-Objects they are equal, but the first is more readable (imho): \$\endgroup\$ – Tim Schmelter Jul 13 '12 at 22:30
6
votes
\$\begingroup\$

Assuming LINQ to objects (i. e. these are in-memory collections not LINQ to Entities IQueryables or something):

Will statement 2. call GetMyListB() for each item in ListA?

Yes. If you want to avoid this, you'll have to store the result of GetMyListB() outside the function.

Which is more readable?

In my opinion two are about equally readable, although I would change #2 to be:

bool overlap = GetMyListA().Any(GetMyListB().Contains); // 2.

As far as performance, #1 will probably perform better in most cases, since it will dump all of one list into a hash table and then do an O(1) lookup for each element in the other list. Two exceptions to this that I can think of are (1) if the lists are very small, then building the hash table data structure might not be worth the overhead and (2) option 2 can theoretically return without having considered every element in either list. If the lists are large lazy enumerables and you expect this to return true in most cases then this could lead to a performance increase.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.