Thursday, March 05, 2009

LINQ Benchmark

For those of you that doesn't know LINQ yet, it's a new technology from c# 3.0 that lets you run queries independently from your database, even on c# objects (like arrays, List, LinkedList, etc) with a SQL-like statement .

Yesterday I was wondering how fast LINQ could run some queries compared to more traditional methods. I'm not talking about LINQ to SQL on an external database, but running a query on some IEnumerable object instead. So I created a small benchmark. I'm not sure if it is correct because there is some stuff that I might be timing erroneously, so please tell me if I should be considering things like JIT time, GC, or any other housekeeping.

Anyway, on a very simple test the results came out unexpectedly.

Here's the method I wrote:



static void Main(string[] args)
{
int valueCount = 1000000;
Random random = new Random();
float[] values = new float[valueCount];

Stopwatch timer;
// Initialize the values
for (int i = 0; i < valueCount; i++)
{
values[i] = random.Next(valueCount);
}
GC.Collect();


// LINQ
Console.WriteLine("Try with the LINQ query");
timer = Stopwatch.StartNew();
IEnumerable<float> extracted1 = from v in values where v < 500000 select v;
timer.Stop();
Console.WriteLine(timer.Elapsed.TotalSeconds);
Console.ReadLine();

// Regular for
Console.WriteLine("Try with the 'for' iteration");
List<float> extracted2 = new List<float>();
timer = Stopwatch.StartNew();
float var;
for (int i = 0; i < valueCount; i++)
{
var = values[i];
if (var < 500000)
extracted2.Add(var);
}
timer.Stop();
Console.WriteLine(timer.Elapsed.TotalSeconds);
Console.WriteLine(String.Format("Counts: {0}, {1}", extracted1.Count(), extracted2.Count()));
Console.ReadLine();
}

It creates an array of random values ranging from 0 up to 1 million. Then both tests try to extract 500000 numbers from the values given the simple rule (x < 500000). So here are the results:

This is one of the results I got. LINQ was 50 times faster??? Am I measuring this wrong?

JG

1 comments:

Anonymous said...

LINQ is just providing you with an IEnumerable<> which is not actually iterating immediately. Force it into a list/array and that will give you the results you want. (some member function on the IEnumerable should be able to convert it)