In particular, if you are querying over a large number of items in a collection or
array, regardless of the item type, LINQ can be much slower than a typical foreach
loop with the appropriate "if tests".
I put together some sample code to test the performance of LINQ vs foreach loops
over a large array of strings, and as well, over a large collection of integers.
Let's look at the code and then the output and draw some conclusions:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace LINQPerformance
{
class LINQPerfTest
{
static string[] strArray;
static string[] strTest;
private const int number = 1000; //Change this number to size the Array
public static void Main()
{
FillArrayWithGuids();
FindTenElements();
Console.WriteLine("Using For Each loop with Strings:");
UseForEachLoop();
Console.WriteLine("Using LINQ With Strings:");
UseLinq();
Console.WriteLine("Use Foreach with int:");
UseForeachWithIf();
Console.WriteLine("Use LINQ Where with int:");
UseLinqWhereQuery();
Console.ReadKey();
}
private static void UseForEachLoop()
{
Stopwatch sw = new Stopwatch();
for (int i = 0; i < 10; i++)
{
sw.Start();
foreach (var item in strArray)
{
if (item == strTest[i])
{
sw.Stop();
Console.Write(" Item found in {0} ticks\n", sw.ElapsedTicks.ToString());
break;
}
}
}
}
private static void UseLinq()
{
Stopwatch sw = new Stopwatch();
for (int i = 0; i < 10; i++)
{
sw.Start();
var qry = from x in strArray
where x == strTest[i]
select x;
foreach (var item in qry)
{
}
sw.Stop();
Console.Write(" Item found in {0} ticks\n", sw.ElapsedTicks.ToString());
}
}
// Initialize Array and retrieve 10 elements for comparison
private static void FillArrayWithGuids()
{
//Fill the string Array with GUIDs
strArray = new string[number * 10];
for (int i = 0; i < number * 10; i++)
{
strArray[i] = System.Guid.NewGuid().ToString();
}
}
private static void FindTenElements()
{
//Find 10 elements from the big array for comparison
//We are finding the elements from different locations to see if that has any affect
on performance
strTest = new string[10];
strTest[0] = strArray[0 * number];
strTest[1] = strArray[1 * number];
strTest[2] = strArray[2 * number];
strTest[3] = strArray[3 * number];
strTest[4] = strArray[4 * number];
strTest[5] = strArray[5 * number];
strTest[6] = strArray[6 * number];
strTest[7] = strArray[7 * number];
strTest[8] = strArray[8 * number];
strTest[9] = strArray[9 * number];
}
// Work with List<int> performing standard foreach with "if test"
private static void UseForeachWithIf()
{
int ctr = 0;
List<int> ints = new List<int>();
for (var i = 0; i < 10000000; i++)
{
ints.Add(i);
}
Stopwatch sw = Stopwatch.StartNew();
foreach (var item in ints)
{
if (item % 2 == 0) ctr++;
}
sw.Stop();
Console.Write(" Foreach took {0} ticks\n", sw.ElapsedTicks.ToString());
}
// Work with List<int> performing LINQ Where test
private static void UseLinqWhereQuery()
{
int ctr = 0;
List<int> ints = new List<int>();
for (var i = 0; i < 10000000; i++)
{
ints.Add(i);
}
Stopwatch sw = Stopwatch.StartNew();
foreach (var item in ints.Where( x=>x%2==0))
{
ctr++;
}
sw.Stop();
Console.Write(" LINQ Where took {0} ticks\n", sw.ElapsedTicks.ToString());
}
}
}
Here is sample Console Output:

As can be seen, in both the string and the int cases, LINQ with a where clause or
query is significantly slower than a standard foreach loop with "if tests"
in the loop -- so much so that it behooves developers to be aware of this impediment
whenever attempting to do iterations over an array or collection. LINQ queries
to find strings in a large collection or array can be from 2 to as much as 32 times slower than using a standard foreach loop, depending on how the LINQ query is constructed.
If you are going to use LINQ, it is important to test. There are many ways to write
a LINQ query. For example, examine the two queries below:
var qry = from x in strArray where x == strTest[i] select x;
var qry = strArray.First(x => x == strTest[i]);
Both queries will return the same result in this demo , but one of them, if used
in the demo code above, is significantly faster. Do you know which one?
Where raw performance is an issue, I would be inclined not to use LINQ unless there
are other overriding reasons to do so.
You can download the sample test solution here.