烘焙方法意味着什么?

时间:2012-02-21 22:53:44

标签: c# stack-trace

我在SO {

上使用的micro ORM上阅读了这篇文章

作者展示了这个堆栈跟踪:

System.Reflection.Emit.DynamicMethod.CreateDelegate
System.Data.Linq.SqlClient.ObjectReaderCompiler.Compile
System.Data.Linq.SqlClient.SqlProvider.GetReaderFactory
System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Compile
System.Data.Linq.CommonDataServices+DeferredSourceFactory`1.ExecuteKeyQuery
System.Data.Linq.CommonDataServices+DeferredSourceFactory`1.Execute
System.Linq.Enumerable.SingleOrDefault
System.Data.Linq.EntityRef`1.get_Entity

然后说:

  

在上面的描述中你可以看到'EntityRef'正在烘焙一个方法,这不是问题,除非它每秒发生100次。

有人可以通过“烘焙方法”解释堆栈跟踪与他的意思有关吗?为什么会出现性能问题?

3 个答案:

答案 0 :(得分:10)

当您执行以下操作时:

int[] items = whatever;
IEnumerable<int> query = from item in items where item % 2 == 0 select item;

然后编译器将其转换为:

static bool Predicate(int item) { return item % 2 == 0; }
...
IEnumerable<int> query = Enumerable.Where<int>(items, new Func<int, bool> (Predicate));

即,编译器为该方法生成IL。在运行时构建查询对象时,Where返回的对象保留在谓词的委托上,并在必要时执行谓词。

但是如果你愿意,可以在运行时为代理构建 IL。你所做的是将谓词的主体保存为表达式树。在运行时,表达式树可以动态地将自身编译为全新的IL;基本上我们启动了一个非常简化的编译器,它知道如何为表达式树生成IL。这样,您可以在运行时更改谓词的详细信息,并重新编译谓词,而无需重新编译整个程序。

该评论的作者使用“烘焙”作为“动态轻量级代码生成”的俚语。

答案 1 :(得分:1)

它指的是在运行时动态创建方法,例如使用表达式树。将表达式树编译为方法并返回已编译方法的委托可称为“烘焙”该方法。

答案 2 :(得分:0)

这是一种奇特的方式,说他们使用Reflection.Emit发出动态代码。一个众所周知的缓慢过程。