views:

62

answers:

3

Hi,

Learning a bit about Linq. I have the following code:

(Please excuse the pathetic size of the data set)

class Program
{
    static void Main(string[] args)
    {
        var employees = new List<Employee>
                            {
                                new Employee
                                    {
                                        Name = "Bill Bailey",
                                        EmployeeCode = 12345,
                                        Department = "Comedy Lab",
                                        DateOfBirth = DateTime.Parse("13/01/1964"),
                                        CurrentEmployee = true
                                    },
                                new Employee
                                    {
                                        Name = "Boris Johnson",
                                        EmployeeCode = 56789,
                                        Department = "Cycling Dept.",
                                        DateOfBirth = DateTime.Parse("19/06/1964"),
                                        CurrentEmployee = true
                                    },
                                new Employee
                                    {
                                        Name = "Bruce Forsyth",
                                        EmployeeCode = 5,
                                        Department = "Comedy Lab",
                                        DateOfBirth = DateTime.Parse("22/03/1928"),
                                        CurrentEmployee = false
                                    },
                                new Employee
                                    {
                                        Name = "Gordon Brown",
                                        EmployeeCode = 666,
                                        Department = "Backbenches",
                                        DateOfBirth = DateTime.Parse("20/02/1951"),
                                        CurrentEmployee = false
                                    },
                                new Employee
                                    {
                                        Name = "Russell Howard",
                                        EmployeeCode = 46576,
                                        Department = "Comedy Lab",
                                        DateOfBirth = DateTime.Parse("23/03/1980"),
                                        CurrentEmployee = false
                                    }
                            };

        Func<Employee, bool> oapCalculator = (employee => employee.DateOfBirth.AddYears(65) < DateTime.Now);

        var oaps1 = employees.Where(oapCalculator);
        var oaps2 = (from employee in employees
                     where oapCalculator(employee)
                     select employee);

        oaps1.ToList().ForEach(employee => Console.WriteLine(employee.Name));
        oaps2.ToList().ForEach(employee => Console.WriteLine(employee.Name));

        Console.ReadLine();
    }

    class Employee
    {
        public string Name { get; set; }
        public int EmployeeCode { get; set; }
        public string Department { get; set; }
        public DateTime DateOfBirth { get; set; }
        public bool CurrentEmployee { get; set; }
    }
}

I have a few questions:

As far as I can tell, both of the featured Linq queries are doing the same thing (black magic may be afoot).

  1. Would they both be compiled down to the same IL?
  2. If not, why, and which would be the most efficient given a sizable amount of data?
  3. What is the best way to monitor Linq query efficiency? Performance timers or something built-in?
  4. Is the lambda expression the preferred method, as it is the most concise?
  5. In a department of lambda fearing luddites, is it worth taking the plunge and teaching 'em up or using the SQL-esque syntax?

Thanks

A: 

Both LINQ queries are equivalent. The second uses syntactic sugar that the compiler translates to an expression similar to your first query before compiling. As far as what is preferred, use whatever seems more readable to you and your team.

Darin Dimitrov
+3  A: 

Re

var oaps1 = employees.Where(oapCalculator);

vs

var oaps2 = (from employee in employees
             where oapCalculator(employee)
             select employee);

There is a slight difference, in particular around the where oapCalculator(employee). The second query is mapped to:

var oaps2 = employees.Where(employee => oapCalculator(employee));

so this is an extra layer of delegate, and will also incur the (small) overhead of a capture-class due to the closure over the variable oapCalculator, and a dereference of this per iteration. But otherwise they are the same. In particular, the Select is trivially removed (in accordance with the spec).

In general, use whichever is clearest in any scenario. In this case, either seems fine, but you will find it easier to use .Where etc if you are regularly dealing in scenarios that involving delegates or Expressions.

Marc Gravell
+2  A: 

I don't mean this to be snide, but sometimes it is better to try things out for yourself. Along those lines, here are some tools, and some of my own experiences.

1 and 2: Disassemble and find out! :) http://www.red-gate.com/products/reflector/

3: Profile your app. This is the answer to any perf-determining question, unless you're doing algorithm work (mathematical proofs, big-o). Profiling tools are built into VS.

4: Which do you prefer? How about your co-workers? This sounds like a statistical question, which would require a survey

5: Similar to 4, try it and find out! As you may have experienced, evangelizing new techniques to your co-workers will teach you as much as it will teach them.

I've found I've had about a 50% success rate w/ teaching general delegate/lambda usage. I made sure to come up with practical examples from my production test code, and showed how the equivalent imperative code had lots of duplication.

I tried going through the free SICP videos with my team (being a really eye-opener on refactoring), and I found it a pretty hard sell. LISP isn't the most attractive language to the majority of programmers...

http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/

Merlyn Morgan-Graham
Point 5 is an important one, teaching and explaining a concept is by far the best way to learn something and cement it in your mind!
SLC
Quite, I might use the code in question to determine how many employees of OAP age are in the company. They should remember that...
fletcher