Skip to content

Instantly share code, notes, and snippets.

@keith-kurak
Last active December 2, 2016 13:06
Show Gist options
  • Save keith-kurak/7a57ba863e8c05a3753a52dfeeaf097e to your computer and use it in GitHub Desktop.
Save keith-kurak/7a57ba863e8c05a3753a52dfeeaf097e to your computer and use it in GitHub Desktop.
Simple match Big-O comparison
public class SomeContainerOfThings
{
List<IThing> Things {get;set;}
//old - performed at O(N^2)
IEnumerable<IThing> GetThingsAlsoIn(SomeContainerOfThings other)
{
return this.Things.Where(thisThing => other.Things.Any(otherThing => thisThing.Name == otherThing.Name));
}
//new - performed at 2 O(N)
IEnumerable<IThing> GetThingsAlsoIn(SomeContainerOfThings other)
{
var indexedThings = this.Things.ToDictionary(thing => thing.Name);
return other.Things.Where(otherThing => indexedThings.ContainsKey(otherThing.Name);
}
}
[TestClass]
public class SomeContainerOfThingsTests
{
private SomeContainerOfThings GetFakeContainerForRange(int nameStart, int nameEnd)
{
//... (this gets a container containing one IThing for each number between the start and the end)
}
private class CountingThing: IThing
{
public TimesAccessed {get;set;}
private string name;
public Name
{
get
{
this.TimesAccessed++;
return this.name;
}
set
{
this.Name = value;
}
}
}
//sums together TimesAccessed of each CounterThing in the two containers
private int GetTotalTimesAccessed(SomeContainerOfThings container1, SomeContainerOfThings container2)
{
return container1.Things.Sum(t => (t as CounterThing).TimesAccessed) + container2.Things.Sum(t => (t as CounterThing).TimesAccessed)
}
[TestMethod]
public void GetThingsAlsoIn_PerformsAtBigOofNLevel()
{
//arrange
var container1 = GetFakeContainerForRange(1, 1000); //worst case = best case. This algorithm takes 2 O(n) regardless
var container2 = GetFakeContainerForRange(1, 1000);
//act
container1.GetThingsAlsoIn(container2).ToList(); //force enumeration
//assert
var timesAccessed = GetTotalTimesAccessed(container1, container2);
Assert.IsTrue(timesAccessed <= 2000);
}
//old algorithm extracted to show how bad it performs
[TestMethod]
public void GetThingsAlsoIn_OldAlgorithm_PerformsAtBigOofNSquaredLevel()
{
//arrange
var container1 = GetFakeContainerForRange(1, 1000); //worst case for this algorithm = no matches
var container2 = GetFakeContainerForRange(1001, 2000);
//act
//copy algorithm right in since its no longer in current version
container1.Things.Where(thisThing => container2.Things.Any(otherThing => thisThing.Name == otherThing.Name)).ToList();
//assert
var timesAccessed = GetTotalTimesAccessed(container1, container2);
Assert.IsTrue(timesAccessed == 1000000);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment