Skip to content

Instantly share code, notes, and snippets.

@cdiggins
Created March 11, 2022 19:31
Show Gist options
  • Save cdiggins/a0fb87d7e7bc2f6185d03c94294c4a6f to your computer and use it in GitHub Desktop.
Save cdiggins/a0fb87d7e7bc2f6185d03c94294c4a6f to your computer and use it in GitHub Desktop.
On the Importance of Inlining
[Test]
public static void Inlining()
{
var length = 1000;
// Our Two Lambdas
Func<int, bool> Lt5 = x => x < 5;
Func<int, int, int> AddInts = (x, y) => x + y;
// Original expression
var r = length.Range().Where(Lt5).Aggregate(0, AddInts);
// Expansion 1 (Intermediate variable assignment)
{
var x0 = length.Range();
var x1 = x0.Where(Lt5);
var x2 = x1.Aggregate(0, AddInts);
Assert.AreEqual(x2, r);
}
// Expansion 2 (Inline function)
{
var x0 = new RangeSequence(0, 1000);
var x1 = x0.Iterator.Where(Lt5).ToSequence();
var x2 = x1.Iterator.Aggregate(0, AddInts);
Assert.AreEqual(x2, r);
}
// Expansion 3 (Intermediate variable assignment #2)
{
var x0 = new RangeSequence(0, 1000);
var x1 = x0.Iterator;
var x2 = x1.Where(Lt5);
var x3 = x2.ToSequence();
var x4 = x3.Iterator;
var x5 = x4.Aggregate(0, AddInts);
Assert.AreEqual(x5, r);
}
// Expansion 4: Inline Aggregate
{
var x0 = new RangeSequence(0, 1000);
var x1 = x0.Iterator;
var x2 = x1.Where(Lt5);
var x3 = x2.ToSequence();
var x4 = x3.Iterator;
var init = 0;
while (x4.HasValue)
{
init = AddInts(init, x4.Value);
x4= x4.Next;
}
Assert.AreEqual(init, r);
}
// Expansion 5: Coalescing some null operations.(x = this), inlining more functions
{
var x0 = new RangeSequence(0, 1000);
var x1 = new WhereIterator<int>(x0, Lt5);
var init = 0;
while (x1.HasValue)
{
init = AddInts(init, x1.Value);
x1 = new WhereIterator<int>(x1.Source.Next, Lt5);
}
Assert.AreEqual(init, r);
}
// Expansion 6: Expanding WhereIterator to local variables
// NOTE: this step requires casting to work properly.
{
var x1_Source = new RangeSequence(0, 1000);
var x1_Predicate = Lt5;
while (x1_Source.HasValue && !x1_Predicate(x1_Source.Value))
{
x1_Source = (RangeSequence)x1_Source.Next;
}
var init = 0;
while (x1_Source.HasValue)
{
init = AddInts(init, x1_Source.Value);
x1_Source = (RangeSequence)x1_Source.Next;
x1_Predicate = x1_Predicate;
while (x1_Source.HasValue && !x1_Predicate(x1_Source.Value))
{
x1_Source = (RangeSequence)x1_Source.Next;
}
}
Assert.AreEqual(init, r);
}
// Expansion 7: Inlining more function calls.
{
var x1_Source = new RangeSequence(0, 1000);
while ((x1_Source.Count > 0) && !Lt5(x1_Source.From))
{
x1_Source = new RangeSequence(x1_Source.From + 1, x1_Source.Count - 1);
}
var init = 0;
while ((x1_Source.Count > 0))
{
init = AddInts(init, x1_Source.From);
x1_Source = new RangeSequence(x1_Source.From + 1, x1_Source.Count - 1);
while ((x1_Source.Count > 0) && !Lt5(x1_Source.From))
{
x1_Source = new RangeSequence(x1_Source.From + 1, x1_Source.Count - 1);
}
}
Assert.AreEqual(init, r);
}
// Expansion 8: Expanding the RangeSequence to local variables
{
var x1_Source_From = 0;
var x1_Source_Count = 1000;
while ((x1_Source_Count > 0) && !Lt5(x1_Source_From))
{
x1_Source_From = x1_Source_From + 1;
x1_Source_Count = x1_Source_Count - 1;
}
var init = 0;
while (x1_Source_Count > 0)
{
init = AddInts(init, x1_Source_From);
x1_Source_From = x1_Source_From + 1;
x1_Source_Count = x1_Source_Count - 1;
while ((x1_Source_Count > 0) && !Lt5(x1_Source_From))
{
x1_Source_From = x1_Source_From + 1;
x1_Source_Count = x1_Source_Count - 1;
}
}
Assert.AreEqual(init, r);
}
// Expansion 9 (Lambda Expansion)
{
var x1_Source_From = 0;
var x1_Source_Count = 1000;
while ((x1_Source_Count > 0) && !(x1_Source_From < 5))
{
x1_Source_From = x1_Source_From + 1;
x1_Source_Count = x1_Source_Count - 1;
}
var init = 0;
while (x1_Source_Count > 0)
{
init = init + x1_Source_From;
x1_Source_From = x1_Source_From + 1;
x1_Source_Count = x1_Source_Count - 1;
while ((x1_Source_Count > 0) && !(x1_Source_From < 5))
{
x1_Source_From = x1_Source_From + 1;
x1_Source_Count = x1_Source_Count - 1;
}
}
Assert.AreEqual(init, r);
}
// Expansion 10 (Assignment Simplification)
{
var x1_Source_From = 0;
var x1_Source_Count = 1000;
while ((x1_Source_Count > 0) && !(x1_Source_From < 5))
{
x1_Source_From += 1;
x1_Source_Count -= 1;
}
var init = 0;
while (x1_Source_Count > 0)
{
init += x1_Source_From;
x1_Source_From += 1;
x1_Source_Count -= 1;
while ((x1_Source_Count > 0) && !(x1_Source_From < 5))
{
x1_Source_From += 1;
x1_Source_Count -= 1;
}
}
Assert.AreEqual(init, r);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment