Vlad Bezden
Vlad Bezden

Reputation: 89577

Which LINQ expression is faster

Hi All

In following code

public class Person
{
    public string Name { get; set; }
    public uint Age { get; set; }
    
    public Person(string name, uint age)
    {
        Name = name;
        Age = age;
    }
}

void Main()
{
    var data = new List<Person>{ new Person("Bill Gates", 55), 
                                new Person("Steve Ballmer", 54), 
                                new Person("Steve Jobs", 55), 
                                new Person("Scott Gu", 35)};
    
    // 1st approach
    data.Where (x => x.Age > 40).ToList().ForEach(x => x.Age++);
    
    // 2nd approach
    data.ForEach(x => 
                    {
                        if (x.Age > 40)
                            x.Age++;
                    });
                    
    data.ForEach(x => Console.WriteLine(x));    
}

in my understanding 2nd approach should be faster since it iterates through each item once and first approach is running 2 times:

  1. Where clause
  2. ForEach on subset of items from where clause.

However internally it might be that compiler translates 1st approach to the 2nd approach anyway and they will have the same performance.

Any suggestions or ideas?

I could do profiling like suggested, but I want to understand what is going on compiler level if those to lines of code are the same to the compiler, or compiler will treat it literally.

Upvotes: 0

Views: 247

Answers (5)

Amy B
Amy B

Reputation: 110111

You argue against .Where() without measurement. The real difference between the two approaches is the .ToList().

3rd approach:

foreach(Person x in data.Where(x => x.Age > 40))
{
  x.Age++; 
}

Upvotes: 2

Randy Minder
Randy Minder

Reputation: 48402

Paste the code into LinqPad (www.linqpad.net) and time it. Or you can examine the generated IL code to see how the compiler handles it.

Upvotes: 1

Brennan Vincent
Brennan Vincent

Reputation: 10665

If you're interested in how the compiler treats these two expressions, why not compile each, then use the ildasm tool (bundled with Visual Studio) to look at the code generated?

Upvotes: 0

Hogan
Hogan

Reputation: 70523

I believe the first one will be slow because of ToList(). Creating a new data structure has to be relatively slow.

Upvotes: 1

kemiller2002
kemiller2002

Reputation: 115488

I just ran the code and the second runs faster:

static void T3()
        {
            var data = new List<Person>{ new Person("Bill Gates", 55), 
                                new Person("Steve Ballmer", 54), 
                                new Person("Steve Jobs", 55), 
                                new Person("Scott Gu", 35)};

            System.Diagnostics.Stopwatch s1 = new System.Diagnostics.Stopwatch();

            s1.Start();
            // 1st approach
            data.Where(x => x.Age > 40).ToList().ForEach(x => x.Age++);
            s1.Stop();

            System.Diagnostics.Stopwatch s2 = new System.Diagnostics.Stopwatch();

            s2.Start();
            // 2nd approach
            data.ForEach(x =>
            {
                if (x.Age > 40)
                    x.Age++;
            });
            s2.Stop();

            Console.Write("s1: " + s1.ElapsedTicks + " S2:" + s2.ElapsedTicks);
            data.ForEach(x => Console.WriteLine(x));
        }

This is to be expected, since the second doesn't need to convert to a list and then run the foreach method.

Results: s1: 1192 S2:255

Upvotes: 3

Related Questions