My doubt, what would be better in terms of performance?
Both syntax are equal for the compiler that converts into the same code, no charge as it is Compile time.
The code below is the post quoted by Tobymosque, only in the right way. I will discuss below.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
namespace IterationPerformanceTest
{
class Program
{
const int SIZE = 10000;
const int RUNS = 1000;
static Stopwatch stopwatch = new Stopwatch();
static Random r = new Random();
static List<int> intList = new List<int>();
public static void Main(string[] args)
{
for (int i = 0; i < SIZE; i++)
intList.Add(r.Next(int.MinValue, int.MaxValue));
RunLoop();
RunQuerySyntax();
RunFluentSyntax();
Console.ReadLine();
}
static void RunQuerySyntax()
{
stopwatch.Reset();
//Query Syntax
stopwatch.Start();
for (int t = 0; t < RUNS; ++t)
{
var result = (from int i in intList where i < 10 select i).ToList();
}
stopwatch.Stop();
Console.WriteLine(string.Format("Query Syntax : {0}, avg. {1}", stopwatch.Elapsed, new TimeSpan(stopwatch.ElapsedTicks / RUNS)));
}
static void RunFluentSyntax()
{
stopwatch.Reset();
//Fluent Syntax
stopwatch.Start();
for (int t = 0; t < RUNS; ++t)
{
var result = intList.Where(i => i < 10).ToList();
}
stopwatch.Stop();
Console.WriteLine(string.Format("Fluent Syntax: {0}, avg. {1}", stopwatch.Elapsed, new TimeSpan(stopwatch.ElapsedTicks / RUNS)));
}
static void RunLoop()
{
stopwatch.Reset();
//LOOP
stopwatch.Start();
for (int t = 0; t < RUNS; ++t)
{
var result = new List<int>();
foreach (var i in intList)
{
if (i < 10) result.Add(i);
}
}
stopwatch.Stop();
Console.WriteLine(string.Format("Loop: {0}, avg. {1}", stopwatch.Elapsed, new TimeSpan(stopwatch.ElapsedTicks / RUNS)));
}
}
}
I isolated the calls to make it easy on CIL to analyze and something else...
Loop of Query Syntax:
// loop start (head: IL_004a)
IL_0010: nop
IL_0011: ldsfld class [mscorlib]System.Collections.Generic.List`1<int32> IterationPerformanceTest.Program::intList
IL_0016: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Cast<int32>(class [mscorlib]System.Collections.IEnumerable)
IL_001b: ldsfld class [mscorlib]System.Func`2<int32, bool> IterationPerformanceTest.Program::'CS$<>9__CachedAnonymousMethodDelegate1'
IL_0020: brtrue.s IL_0035
IL_0022: ldnull
IL_0023: ldftn bool IterationPerformanceTest.Program::'<RunQuerySyntax>b__0'(int32)
IL_0029: newobj instance void class [mscorlib]System.Func`2<int32, bool>::.ctor(object, native int)
IL_002e: stsfld class [mscorlib]System.Func`2<int32, bool> IterationPerformanceTest.Program::'CS$<>9__CachedAnonymousMethodDelegate1'
IL_0033: br.s IL_0035
IL_0035: ldsfld class [mscorlib]System.Func`2<int32, bool> IterationPerformanceTest.Program::'CS$<>9__CachedAnonymousMethodDelegate1'
IL_003a: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<int32>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>, class [mscorlib]System.Func`2<!!0, bool>)
IL_003f: call class [mscorlib]System.Collections.Generic.List`1<!!0> [System.Core]System.Linq.Enumerable::ToList<int32>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>)
IL_0044: stloc.1
IL_0045: nop
IL_0046: ldloc.0
IL_0047: ldc.i4.1
IL_0048: add
IL_0049: stloc.0
IL_004a: ldloc.0
IL_004b: ldc.i4 1000
IL_0050: clt
IL_0052: stloc.2
IL_0053: ldloc.2
IL_0054: brtrue.s IL_0010
// end loop
Loop of Fluent Syntax
// loop start (head: IL_0045)
IL_0010: nop
IL_0011: ldsfld class [mscorlib]System.Collections.Generic.List`1<int32> IterationPerformanceTest.Program::intList
IL_0016: ldsfld class [mscorlib]System.Func`2<int32, bool> IterationPerformanceTest.Program::'CS$<>9__CachedAnonymousMethodDelegate3'
IL_001b: brtrue.s IL_0030
IL_001d: ldnull
IL_001e: ldftn bool IterationPerformanceTest.Program::'<RunFluentSyntax>b__2'(int32)
IL_0024: newobj instance void class [mscorlib]System.Func`2<int32, bool>::.ctor(object, native int)
IL_0029: stsfld class [mscorlib]System.Func`2<int32, bool> IterationPerformanceTest.Program::'CS$<>9__CachedAnonymousMethodDelegate3'
IL_002e: br.s IL_0030
IL_0030: ldsfld class [mscorlib]System.Func`2<int32, bool> IterationPerformanceTest.Program::'CS$<>9__CachedAnonymousMethodDelegate3'
IL_0035: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<int32>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>, class [mscorlib]System.Func`2<!!0, bool>)
IL_003a: call class [mscorlib]System.Collections.Generic.List`1<!!0> [System.Core]System.Linq.Enumerable::ToList<int32>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>)
IL_003f: stloc.1
IL_0040: nop
IL_0041: ldloc.0
IL_0042: ldc.i4.1
IL_0043: add
IL_0044: stloc.0
IL_0045: ldloc.0
IL_0046: ldc.i4 1000
IL_004b: clt
IL_004d: stloc.2
IL_004e: ldloc.2
IL_004f: brtrue.s IL_0010
// end loop
Practically twins!
Note the fact that the example has refactored the calls in isolated methods, try to change the order of Fluent with the Query and depending on your processor/ the bottom will always be slightly faster, this has nothing to do with query performance and yes cache hit, each machine will have a different gain, since it is always the same collection to be traversed, if it is in the processor cache is faster.
Very careful with the examples on the internet, this quoted contained several errors of analysis and technique.
I also think that with LINQ becomes clearer. Using Lambda Expressions, expressions like
Join
and theGroupJoin
They get a little fuzzy and the code gets too long. My boss thinks with Lambda the darlings get faster, but I’m in doubt, too. Sometimes I notice that it is faster with Lambda but there are queries in LINQ that are also fast. It depends on the query that is made– Ninita
Friend, both are Latin, the first case is "query Expression" and the second "lambda Expression". Internally "query Expression" are converted to "lambda Expression", due to this "lambda" is a little faster than "query", but I believe that this small gain does not compensate the legibility loss, finally you can look at the following website for a comparison: http://blog.thijssen.ch/2009/02/linq-vs-lambda-vs-loop-performance-test.html
– Tobias Mesquita
There is no significant performance gain or loss considering both scenarios, since LINQ or so the expression methods are just ways to build a command that generates an SQL.
– Leonel Sanches da Silva