C# Optimization - Performance degradation when using LINQ with a foreach
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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