axeman
axeman

Reputation: 515

Which is more efficient a method returning a Func<bool> or returning bool?

I am refactoring some LINQ queries and am trying to determine the most efficient refactor.

The original line is a query similar to:

  static void Main() {
     var list = new List<string> { "A", "BB", "CCC" };
     var shortList = list.Any(name => name.Length == 1);
  }

I can refactor out the string length check to a method as follows:

  static void Main() {
     var list = new List<string> { "A", "BB", "CCC" };
     var shortList = list.Any(name => IsShort(name));
  }

  private static bool IsShort(string name) {
     return name.Length == 1;
  }

OR, I can refactor out the complete Func to a method:

  static void Main() {
     var list = new List<string> { "A", "BB", "CCC" };
     var shortList = list.Any(IsShortFunc());
  }

  private static Func<string, bool> IsShortFunc() {
     return name => name.Length == 1;
  }

The question is, which is more efficient at run time?

Upvotes: 1

Views: 134

Answers (3)

Jon Skeet
Jon Skeet

Reputation: 1500235

Actually you can do better than that using a method group conversion to construct the delegate:

static void Main() {
   var list = new List<string> { "A", "BB", "CCC" };
   var shortList = list.Any(IsShort);
}

private static bool IsShort(string name) {
   return name.Length == 1;
}

This will have one less level of indirection than your first solution, and it's more readable (IMO) than your second version. If you don't have to think in higher order functions, don't :)

I'd expect the differences in efficiency to be absolutely miniscule though. You should be focusing on readability unless you have really good evidence that the most readable solution isn't performing as well as you need it to.

Upvotes: 3

vgru
vgru

Reputation: 51214

You are basically using Func<string,bool> in any of these cases. At the moment your query starts executing, your delegate is already ready for use and it doesn't really matter if you used an anonymous delegate, a named method, or if some other method created this same delegate.

Second example should be slightly slower than others, since you do many calls to the IsShort method. This same criteria is inlined in other two examples, so you don't have the overhead of calling a method many times.

In the last example, IsShortFunc() method only gets called once, and creates an anonymous delegate which is then used for the rest of the query. In this case, it is an unnecessary level of abstraction.

Upvotes: 0

Tomas Vana
Tomas Vana

Reputation: 18775

There is yet another way of doing that, you can simply say

 static void Main() {
 var list = new List<string> { "A", "BB", "CCC" };
 var shortList = list.Any(IsShortFunc);
 }

 private static bool IsShortFunc(string name) {
    return name.Length == 1;
 }

However, I would value the readability and expresiveness more than performance in all the cases so I'd simply choose the solution you (and other people) will feel most comfortable reading.

Upvotes: 0

Related Questions