LINQ vs foreach vs for performance test results

20,590

Solution 1

You never execute the LINQ query, you just create it. You should use ToList or ToArray method to force an iteration, probably you won't get a different result because LINQ uses a foreach loop as well.

Edit: LINQ takes a little bit more time because you are iterating over all of the items. But in your other two loops you are breaking the loop as soon as you find a match. Try using FirstOrDefault instead of Where and you should get the same (or similar) result.

people.FirstOrDefault(p => p.Name == name);

Solution 2

the linq one is taking no time because the query is never actually evaluated.

Linq is lazy for most operations, it won't actually do anything until someone starts enumerating the results.

if you added

result.Count(); // add this line, query will be evaluated
linqTime = stopwatch.ElapsedMilliseconds;
stopwatch.Restart();

then i'm pretty sure you'd have a non-zero result for linq.

Share:
20,590
Francisco Aguilera
Author by

Francisco Aguilera

Updated on July 15, 2022

Comments

  • Francisco Aguilera
    Francisco Aguilera over 1 year

    Could somebody explain these results? I know there are duplicate questions, but I have yet to find a single question that came to the same conclusion as my results :o

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace SpeedTest
    {
        class Person
        {    
            public Person(string name)
            {
                this.Name = name;
            }
    
            public string Name { get; set; }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var people = new List<Person>();
                AddTwins("FRANCISCO", people);
                var stopwatch = new Stopwatch();
    
                string name = "OCSICNARF";
    
                long linqTime = 0L;
                long foreachTime = 0L;
                long forTime = 0L;
    
                stopwatch.Start();
                Person person0;
                var result = from person in people
                             where person.Name == name
                             select person;
                person0 = result.First();
                linqTime = stopwatch.ElapsedMilliseconds;
                stopwatch.Restart();
                Person person1;
                foreach (Person p in people)
                {
                    if (p.Name == name)
                    {
                        person1 = p;
                        break;
                    }
                }
                foreachTime = stopwatch.ElapsedMilliseconds;
                stopwatch.Restart();
                Person person2;
                for (int i = 0; i < people.Count; i++)
                {
                    if (people[i].Name == name)
                    {
                        person2 = people[i];
                        break;
                    }
                }
                forTime = stopwatch.ElapsedMilliseconds;
                stopwatch.Stop();
    
                Console.WriteLine(string.Format("LINQ took {0}ms", linqTime));
                Console.WriteLine(string.Format("FOREACH took {0}ms", foreachTime));
                Console.WriteLine(string.Format("FOR took {0}ms", forTime));
            }
    
            static void AddTwins(string name, List<Person> people)
            {
                AddTwins(people, name, "");
            }
    
            private static void AddTwins(List<Person> people, string choices, string chosen)
            {
                if (choices.Length == 0)
                {
                    people.Add(new Person(chosen));
                }
                else
                {
                    for (int i = 0; i < choices.Length; i++)
                    {
                        // choose
                        char c = choices[i];
                        string choose1 = choices.Substring(0, i);
                        string choose2 = choices.Substring(i + 1);
                        choices = choose1 + choose2;
    
                        // explore
                        AddTwins(people, choices, chosen + c);
    
                        // Unchoose
                        string unchoose1 = choices.Substring(0, i);
                        string unchoose2 = choices.Substring(i);
                        choices = unchoose1 + c + unchoose2;
                    }
                }
            }
        }
    }
    

    enter image description here