Skip to content

Instantly share code, notes, and snippets.

@ScottLilly
Created May 23, 2014 13:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ScottLilly/aff8be9033b309fcdff9 to your computer and use it in GitHub Desktop.
Save ScottLilly/aff8be9033b309fcdff9 to your computer and use it in GitHub Desktop.
C# Optimization - Performance degradation when using LINQ with a foreach
namespace Engine
{
public class Employee
{
public string Name { get; set; }
public int Salary { get; set; }
public Employee(string name, int salary)
{
Name = name;
Salary = salary;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Engine;
namespace TestBench
{
public partial class Test : Form
{
public Test()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
const int testIterations = 10;
const int employees = 1000000;
List<TestResult> testResults = new List<TestResult>();
for(int i = 0; i < testIterations; i++)
{
testResults.Add(new TestResult(DurationForTest1(employees), DurationForTest2(employees)));
}
double averageDuration1 = testResults.Average(x => x.Test1.TotalMilliseconds);
double averageDuration2 = testResults.Average(x => x.Test2.TotalMilliseconds);
lblTimeSpan1.Text = averageDuration1.ToString();
lblTimeSpan2.Text = averageDuration2.ToString();
lblDifferencePercentage.Text = (((averageDuration2 - averageDuration1) / averageDuration1) * 100).ToString("N2") + " %";
}
private static List<Employee> BuildEmployeeList(int listSize)
{
List<Employee> employees = new List<Employee>();
for(int i = 1; i <= listSize; i++)
{
employees.Add(new Employee(i.ToString(), i));
}
return employees;
}
private TimeSpan DurationForTest1(int listSize)
{
List<Employee> employees = BuildEmployeeList(listSize);
int listMidPoint = listSize / 2;
DateTime start = DateTime.Now;
foreach(Employee employee in employees)
{
if(employee.Salary <= listMidPoint)
{
employee.Salary = employee.Salary * 2;
}
}
return (DateTime.Now - start);
}
private TimeSpan DurationForTest2(int listSize)
{
List<Employee> employees = BuildEmployeeList(listSize);
int listMidPoint = listSize / 2;
DateTime start = DateTime.Now;
foreach(Employee employee in employees.Where(employee => employee.Salary <= listMidPoint))
{
employee.Salary = employee.Salary * 2;
}
return (DateTime.Now - start);
}
}
}
using System;
namespace Engine
{
public class TestResult
{
public TimeSpan Test1 { get; set; }
public TimeSpan Test2 { get; set; }
public TestResult(TimeSpan test1, TimeSpan test2)
{
Test1 = test1;
Test2 = test2;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment