Below are are functions and tests of anonymous recursion. The first one is true Y-combinator, looks fine and simple, but is quite slow. It takes 1000ms to execute 1 mln iterations. The second is quite ugly because of c(c,item) but works twice faster that first.
I need to make my code simplier, more flexible, more stable(not to create a set of functions and etc if I need the recursive call).
Is there a better way to organize anonymous recursion ?
delegate Action<T> Continuation<T>(Continuation<T> r);
[TestMethod]
public void TestMethod()
{
IObject root = BuildComposite();
Performance.Measure(1000000, () =>
{
Apply(root, h => t =>
{
foreach (IObject item in t.Children)
{
//Console.WriteLine(item.Name);
h(item);
}
});
}, "Time ");
}
private static void Apply(IObject root, Func<Action<IObject>, Action<IObject>> g)
{
Continuation<IObject> action = c => thing => { g(c(c))(thing); };
Action<IObject> target = action(action);
target(root);
}
delegate void Continuation<T>(Continuation<T> r, T n);
[TestMethod]
public void TestMethod()
{
var root = BuildComposite();
Performance.Measure(1000000, () =>
{
Apply(root, (c, thing) =>
{
foreach (var item in thing.Children)
{
//Console.WriteLine(item.Name);
c(c, item);
}
});
},"Time");
}
void Apply(IObject root, Continuation<IObject> f)
{
f(f, root);
}
This took my interest yesterday. I made some tests, this is my try, I've got some speedup. The simpler the delegate, the faster it goes, but some memoization did the trick.
Test code for LinqPad.
references
http://mikehadlow.blogspot.com.br/2009/03/recursive-linq-with-y-combinator.html
Alternative Y combinator definition
http://blogs.msdn.com/b/wesdyer/archive/2007/02/02/anonymous-recursion-in-c.aspx
http://www.justinshield.com/2011/06/recursive-lambda-expressions-in-c-using-ycombinator/