12

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?

CodingIntrigue
  • 75,930
  • 30
  • 170
  • 176
  • 1
    possible duplicate of [Which method performs better: .Any() vs .Count() > 0?](http://stackoverflow.com/questions/305092/which-method-performs-better-any-vs-count-0) – Sadique Mar 18 '14 at 08:59
  • 1
    @al-Khwārizmī Not really, I'd ask the same question about `Count()` and Length and my final question still stands - how do I know without going here for each and every LINQ method – CodingIntrigue Mar 18 '14 at 09:01
  • 3
    It's highly doubtful that either of these forms is the bottleneck in the performance of your application. If you've set performance goals, written code, profiled it, and located the hot spots/bottlenecks, *that's* the time to worry about whether there are different variants that may offer better performance. Instead, what you should generally write is *clear* code that expresses your *intentions*. – Damien_The_Unbeliever Mar 18 '14 at 09:04

5 Answers5

8

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/

ruffin
  • 16,507
  • 9
  • 88
  • 138
Shani Elharrar
  • 667
  • 4
  • 5
6

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.

decPL
  • 5,384
  • 1
  • 26
  • 36
4

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.

Peter
  • 27,590
  • 8
  • 64
  • 84
4

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;
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
3

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.

Selman Genç
  • 100,147
  • 13
  • 119
  • 184