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<s开发者_开发百科tring, bool> IsShortFunc() {
return name => name.Length == 1;
}
The question is, which is more efficient at run time?
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.
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.
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.
精彩评论