## 使用Lambda表达式编写递归函数（性能测试）

2009-09-27 13:23  Jeffrey Zhao  阅读(11861)  评论(4编辑  收藏  举报

1. 普通递归
2. 使用SelfApplicable。
3. 使用Fix

public delegate TResult SelfApplicable<T1, T2, TResult>(
SelfApplicable<T1, T2, TResult> self, T1 arg1, T2 arg2);

public static class LambdaRecursion
{
public static Func<T1, T2, TResult> Fix<T1, T2, TResult>(
Func<Func<T1, T2, TResult>, Func<T1, T2, TResult>> f)
{
return (x, y) => f(Fix(f))(x, y);
}

public static Func<T1, T2, TResult> Self<T1, T2, TResult>(
SelfApplicable<T1, T2, TResult> self)
{
return (x, y) => self(self, x, y);
}
}


class Program
{
static int Fib(int x, int y)
{
return y == 0 ? x : Fib(y, x % y);
}

static void Main(string[] args)
{
Fib(1, 2); // JIT“预热”
var gcdMake = LambdaRecursion.Self<int, int, int>(
(f, x, y) => y == 0 ? x : f(f, y, x % y));
var gcdFix = LambdaRecursion.Fix<int, int, int>(
f => (x, y) => y == 0 ? x : f(y, x % y));

CodeTimer.Initialize();

new List<int> { 10000, 100000, 1000000, 10000000 }.ForEach(n =>
{
CodeTimer.Time("Normal * " + n, n, () => Fib(12345, 29083));
CodeTimer.Time("Make * " + n, n, () => gcdMake(12345, 29083));
CodeTimer.Time("Fix * " + n, n, () => gcdFix(12345, 29083));
});

Console.WriteLine("press enter to exit...");
}
}


Normal * 10000
Time Elapsed:   1ms
CPU Cycles:     3,348,351
Gen 0:          0
Gen 1:          0
Gen 2:          0

Make * 10000
Time Elapsed:   2ms
CPU Cycles:     5,817,875
Gen 0:          0
Gen 1:          0
Gen 2:          0

Fix * 10000
Time Elapsed:   16ms
CPU Cycles:     39,522,627
Gen 0:          7
Gen 1:          0
Gen 2:          0

Normal * 100000
Time Elapsed:   12ms
CPU Cycles:     31,708,838
Gen 0:          0
Gen 1:          0
Gen 2:          0

Make * 100000
Time Elapsed:   17ms
CPU Cycles:     43,155,337
Gen 0:          0
Gen 1:          0
Gen 2:          0

Fix * 100000
Time Elapsed:   116ms
CPU Cycles:     294,786,352
Gen 0:          72
Gen 1:          0
Gen 2:          0

Normal * 1000000
Time Elapsed:   125ms
CPU Cycles:     316,509,017
Gen 0:          0
Gen 1:          0
Gen 2:          0

Make * 1000000
Time Elapsed:   171ms
CPU Cycles:     431,639,898
Gen 0:          0
Gen 1:          0
Gen 2:          0

Fix * 1000000
Time Elapsed:   1,161ms
CPU Cycles:     2,931,048,868
Gen 0:          727
Gen 1:          0
Gen 2:          0

Normal * 10000000
Time Elapsed:   1,258ms
CPU Cycles:     3,165,804,593
Gen 0:          0
Gen 1:          0
Gen 2:          0

Make * 10000000
Time Elapsed:   1,710ms
CPU Cycles:     4,306,322,216
Gen 0:          0
Gen 1:          0
Gen 2:          0

Fix * 10000000
Time Elapsed:   11,057ms
CPU Cycles:     27,856,077,942
Gen 0:          7273
Gen 1:          1
Gen 2:          0