我最近转移到.net 3.0(windows窗体,C#)。我想了解更多关于谓词和lambda表达式的知识。我们应该在哪里使用它们?他们是否提高绩效?以及他们如何在内部工作。谢谢。谓词和lambda表达式
0
A
回答
5
如果你搜索堆栈溢出,你会发现大约一千个答案,解释他们的用途。简而言之 - lambda是一种在想要将它传递给另一个方法的地方编写匿名方法的方法。从技术上讲,与匿名方法的delegate
语法相同,尽管增加了类型推断的功能,所以不需要声明参数类型。谓词是一种接受某个值并返回bool
的方法 - 一个例子是Where
的参数。
不引用任何外部变量的lambda会变成一个私有静态方法,并带有构成名称。如果它引用封闭类的实例成员,它将成为一个实例方法。如果引用了局部变量,那些变量就会被“提升”为编译器生成的类的字段,该类在封闭方法开始运行时分配,并且lambda的主体成为新类中的方法。
至于性能,它们没有太大的差别。它们涉及创建临时对象,但是I find that these are collected extremely efficiently by the GC。
1
如果你想研究C#的不同版本以及它们的不同之处,我建议阅读jon -symet的书C.Sharp.in.Depth。这会让你更好地理解新版本
0
它们是否提高性能?以及他们如何在内部工作。谢谢。
大多数情况下,您永远不会注意到性能受到影响。但是,有一些病理情况会导致性能下降,即过度使用fixed point combinators。
它是一个众所周知的把戏,我们可以使用的Y组合子来写递归lambda函数,但是考虑下面的代码:
using System;
using System.Diagnostics;
namespace YCombinator
{
class Program
{
static Func<T, U> y<T, U>(Func<Func<T, U>, Func<T, U>> f)
{
return f(x => y<T, U>(f)(x));
}
static int fibIter(int n)
{
int fib0 = 0, fib1 = 1;
for (int i = 1; i <= n; i++)
{
int tmp = fib0;
fib0 = fib1;
fib1 = tmp + fib1;
}
return fib0;
}
static Func<int, int> fibCombinator()
{
return y<int, int>(f => n =>
{
switch (n)
{
case 0: return 0;
case 1: return 1;
default: return f(n - 1) + f(n - 2);
}
});
}
static int fibRecursive(int n)
{
switch (n)
{
case 0: return 0;
case 1: return 1;
default: return fibRecursive(n - 1) + fibRecursive(n - 2);
}
}
static void Benchmark(string msg, int iterations, Func<int, int> f)
{
int[] testCases = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20 };
Stopwatch watch = Stopwatch.StartNew();
for (int i = 0; i <= iterations; i++)
{
foreach (int n in testCases)
{
f(n);
}
}
watch.Stop();
Console.WriteLine("{0}: {1}", msg, watch.Elapsed.TotalMilliseconds);
}
static void Main(string[] args)
{
int iterations = 10000;
Benchmark("fibIter", iterations, fibIter);
Benchmark("fibCombinator", iterations, fibCombinator());
Benchmark("fibRecursive", iterations, fibRecursive);
Console.ReadKey(true);
}
}
}
这个程序打印出:
fibIter: 14.8074 fibCombinator: 61775.1485 fibRecursive: 2591.2444
fibCombinator和fibRecursive在功能上是等价的,并且具有相同的计算复杂度,但是由于所有中间对象分配,fibCombinator的速度较慢4100倍。
相关问题
- 1. lambda表达式和词典
- 2. .NET中的lambda表达式和谓词有什么区别?
- 3. 方法签名中的谓词,Lambda表达式
- 4. 在OrderBy中转换Lambda表达式从C#到VB.net谓词
- 5. 如何在lambda表达式参数中扩展谓词
- 6. 如何获得Lambda表达式上的谓词<T>值?
- 7. Lambda表达式抢词典
- 8. 如何创建通用lambda表达式。我的许多实体执行相同的Lambda表达式谓词
- 9. 如何在实体框架中使用lambda表达式和谓词
- 10. 构成表达式:选择器+谓词?
- 11. 表达式与谓词问题
- 12. 如何发送谓词表达式?
- 13. RDF表达谓词程度
- 14. 谓词和列表
- 15. 使用动态比较运算符生成lambda表达式(谓词)
- 16. lambda表达式和的putIfAbsent
- 17. Lambda表达式和搜索
- 18. Lambda表达式和RVO
- 19. C#Lambda表达式和NHibernate
- 20. Proguard的和lambda表达式
- 21. Lambda表达式和InvokeOperation
- 22. @PrepareForTest,@RunWith和lambda表达式
- 23. Delegate.Combine和lambda表达式
- 24. C#lambda表达式和IComparer
- 25. 带有谓词和条件的XPath表达式
- 26. Lambda表达式
- 27. Lambda表达式
- 28. Lambda表达式
- 29. Lambda表达式
- 30. Lambda表达式
也许应该记住,除非他们想要自学有关缺乏构建的语言的历史,否则C#程序员(或实际上,任何后Algol语言的用户)都不会使用Y-组合器来实现递归 - 可以引用自己的命名函数的概念。 – 2009-08-03 18:27:34