Methods such as Count(), ToList(), ToArray(), ToDictionary() or ToLookup() will iterate through items thus executing the query definition. Other methods such as Average(), Sum(), Max() and Min() will also execute the query definition.
If one of those methods mentioned above are called twice then the query definition will be executed again to get the result. The execution can be very expensive as the result may be retrieved from database, network, etc. This is done to get fresh result every time from the source.
To avoid re-executing the query definition in a query expression or standard query operators extension methods, store the result into a collection. When obtaining result from the collection, the query definition won't be run again rather the cached/stored result will be used.
Below is an example to clarify:
static void Main(string[] args) { List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; int invocationsCount = 0; Func<int, int> func = number => { invocationsCount++; return number; }; // 1. define the query expression or extension methods (method invocations) IEnumerable<int> selection = from n in numbers select func(n); //IEnumerable<int> selection = numbers.Select(n => func(n)); Console.WriteLine("1. invocationsCount = {0}", invocationsCount); // 2. do a loop foreach (var item in selection) { } Console.WriteLine("2. invocationsCount = {0}", invocationsCount); // 3. do a count selection.Count(); Console.WriteLine("3. invocationsCount = {0}", invocationsCount); // 4. do an average selection.Average(); Console.WriteLine("4. invocationsCount = {0}", invocationsCount); // 5. do another loop foreach (var item in selection) { } Console.WriteLine("5. invocationsCount = {0}", invocationsCount); // 6. do ToList() and cache it to a collection List<int> collection = selection.ToList(); Console.WriteLine("6. invocationsCount = {0}", invocationsCount); // 7. do the loop on the cache collection foreach (var item in collection) { } Console.WriteLine("7. invocationsCount = {0}", invocationsCount); Console.ReadLine(); }
No comments:
Post a Comment