Question

I have a simple array of objects:

Contact[] contacts = _contactService.GetAllContacts();

I want to test if that method returns any contacts. I really like the LINQ syntax for Any() as it highlights what I am trying to achieve:

if(!contacts.Any()) return;

However, is this slower than just testing the length of the array?

if(contacts.Length == 0) return;

Is there any way I can find out what kind of operation Any() performs in this instance without having to go to here to ask? Something like a Profiler, but for in-memory collections?

Was it helpful?

Solution

There are two Any() methods: 1. An extension method for IEnumerable<T> 2. An extension method for IQueryable<T>

I'm guessing that you're using the extension method for IEnumerable<T>. That one looks like this:

public static bool Any<T>(this IEnumerable<T> enumerable)
{
    foreach (var item in enumerable)
    {
        return true;
    }

    return false;
}

Basically, using Length == 0 is faster because it doesn't involve creating an iterator for the array.

If you want to check out code that isn't yours (that is, code that has already been compiled), like Any<T>, you can use some kind of disassembler. Jetbrains has one for free - http://www.jetbrains.com/decompiler/

OTHER TIPS

I have to completely disagree with the other answers. It certainly does not iterate over the array. It will be marginally slower, as it needs to create an array iterator object and call MoveNext() once, but that cost should be negligible in most scenarios; if Any() makes the code more readable to you, feel free to use it.

Source: Decompiled Enumerable.Any<TSource> code.

If you have a array the Length is in a property of the array. When calling Any you are iterate the array to find the first element. Setting up the enumerator is probably more expensive then just reading the Length property.

In your very case Length is slightly better:

  // Just private field test if it's zero or not
  if (contacts.Length == 0) 
    return;

  // Linq overhead could be added: e.g. a for loop 
  // for (int i = 0; i < contains.Length; ++i) 
  //   return true;
  // plus inevitable private field test (i < contains.Length) 
  if (!contacts.Any()) 
    return;

But the difference seems being negligible.

In general case, however, Any is better, because it stops on the first item found

 // Itterates until 1st item is found 
 if (contains.Any(x => MyCondition(x)))
   return;

 // Itterates the entire collection 
 if (contains.Select(x => MyCondition(x)).Count() > 0) 
   return;

Yes, it is slower because it iterate over the elements.Using Length property is better. But still I don't think there is a significant difference because Any returns true as soon as it finds an item.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top