Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ: Not Any vs All Don't

Often I want to check if a provided value matches one in a list (e.g. when validating):

if (!acceptedValues.Any(v => v == someValue))
{
    // exception logic
}

Recently, I've noticed ReSharper asking me to simplify these queries to:

if (acceptedValues.All(v => v != someValue))
{
    // exception logic
}

Obviously, this is logically identical, perhaps slightly more readable (if you've done a lot of mathematics), my question is: does this result in a performance hit?

It feels like it should (i.e. .Any() sounds like it short-circuits, whereas .All() sounds like it does not), but I have nothing to substantiate this. Does anyone have deeper knowledge as to whether the queries will resolve the same, or whether ReSharper is leading me astray?

like image 762
Mark Avatar asked Jan 27 '12 00:01

Mark


People also ask

What is the difference between any and all in Linq?

All() determines whether all elements of a sequence satisfy a condition. Any() determines whether any element of a sequence satisfies the condition.

What is .ANY in C#?

The C# Linq Any Operator is used to check whether at least one of the elements of a data source satisfies a given condition or not. If any of the elements satisfy the given condition, then it returns true else return false. It is also used to check whether a collection contains some data or not.

What is except in Linq?

LINQ: ExceptIt returns a new collection with elements from the first collection which do not exist in the second collection (parameter collection). Example: Except in method syntax C#


8 Answers

Implementation of All according to ILSpy (as in I actually went and looked, rather than the "well, that method works a bit like ..." I might do if we were discussing the theory rather than the impact).

public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    if (predicate == null)
    {
        throw Error.ArgumentNull("predicate");
    }
    foreach (TSource current in source)
    {
        if (!predicate(current))
        {
            return false;
        }
    }
    return true;
}

Implementation of Any according to ILSpy:

public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    if (predicate == null)
    {
        throw Error.ArgumentNull("predicate");
    }
    foreach (TSource current in source)
    {
        if (predicate(current))
        {
            return true;
        }
    }
    return false;
}

Of course, there could be some subtle difference in the IL produced. But no, no there isn't. The IL is pretty much the same but for the obvious inversion of returning true on predicate match versus returning false on predicate mismatch.

This is linq-for-objects only of course. It's possible that some other linq provider treats one much better than the other, but then if that was the case, it's pretty much random which one got the more optimal implementation.

It would seem that the rule comes down solely to someone feeling that if(determineSomethingTrue) is simpler and more readable than if(!determineSomethingFalse). And in fairness, I think they've a bit of a point in that I often find if(!someTest) confusing* when there's an alternative test of equal verbosity and complexity that would return true for the condition we want to act upon. Yet really, I personally find nothing to favour one over the other of the two alternatives you give, and would perhaps lean very slightly toward the former if the predicate were more complicated.

*Not confusing as in I don't understand, but confusing as in I worry that there's some subtle reason for the decision that I don't understand, and it takes a few mental skips to realise that "no, they just decided to do it that way, wait what was I looking at this bit of code for again?..."

like image 126
Jon Hanna Avatar answered Oct 03 '22 02:10

Jon Hanna


You might find these extension methods make your code more readable:

public static bool None<TSource>(this IEnumerable<TSource> source)
{
    return !source.Any();
}

public static bool None<TSource>(this IEnumerable<TSource> source, 
                                 Func<TSource, bool> predicate)
{
    return !source.Any(predicate);
}

Now instead of your original

if (!acceptedValues.Any(v => v == someValue))
{
    // exception logic
}

you could say

if (acceptedValues.None(v => v == someValue))
{
    // exception logic
}
like image 37
AakashM Avatar answered Oct 03 '22 03:10

AakashM


Both would have identical performance because both stop enumeration after the outcome can be determined - Any() on the first item the passed predicate evaluates to true and All() on the first item the predicate evaluates to false.

like image 36
BrokenGlass Avatar answered Oct 03 '22 03:10

BrokenGlass


All short circuits on the first non-match, so it's not a problem.

One area of subtlety is that

 bool allEven = Enumerable.Empty<int>().All(i => i % 2 == 0); 

Is true. All of the items in the sequence are even.

For more on this method, consult the documentation for Enumerable.All.

like image 41
Anthony Pegram Avatar answered Oct 03 '22 04:10

Anthony Pegram


As other answers have well covered: this is not about performance, it's about clarity.

There's wide support for both of your options:

if (!acceptedValues.Any(v => v == someValue))
{
    // exception logic
}

if (acceptedValues.All(v => v != someValue))
{
    // exception logic
}

But I think this might achieve broader support:

var isValueAccepted = acceptedValues.Any(v => v == someValue);
if (!isValueAccepted)
{
    // exception logic
}

Simply computing the boolean (and naming it) before negating anything clears this up a lot in my mind.

like image 37
Michael Haren Avatar answered Oct 03 '22 04:10

Michael Haren


All() determines whether all elements of a sequence satisfy a condition.
Any() determines whether any element of a sequence satisfies the condition.

var numbers = new[]{1,2,3};

numbers.All(n => n % 2 == 0); // returns false
numbers.Any(n => n % 2 == 0); // returns true
like image 40
emy Avatar answered Oct 03 '22 03:10

emy


If you take a look at the Enumerable source you'll see that the implementation of Any and All is quite close:

public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
    if (source == null) throw Error.ArgumentNull("source");
    if (predicate == null) throw Error.ArgumentNull("predicate");
    foreach (TSource element in source) {
        if (predicate(element)) return true;
    }
    return false;
}

public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
    if (source == null) throw Error.ArgumentNull("source");
    if (predicate == null) throw Error.ArgumentNull("predicate");
    foreach (TSource element in source) {
        if (!predicate(element)) return false;
    }
    return true;
}

There is no way that one method be significantly faster than the other since the only difference lies in a boolean negation, so prefer readability over false performance win.

like image 32
Thomas Ayoub Avatar answered Oct 03 '22 02:10

Thomas Ayoub


According to this link

Any – Checks for at least one match

All – Checks that all match

like image 24
rcarvalhoxavier Avatar answered Oct 03 '22 03:10

rcarvalhoxavier