I was reading this post here on micro ORM used on SO.
The author showed this stack-trace:
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
Then said:
In the trace above you can see that ‘EntityRef’ is baking a method, which is not a problem, unless it is happening 100s of times a second.
Could someone explain the stack-trace in relation to what he meant by “baking a method” and why it would be a performance problem?
When you do something like:
then the compiler turns that into something like:
That is, the compiler generates the IL for the method. When you build the query object at runtime, the object returned by Where holds on to a delegate to the predicate, and executes the predicate when necessary.
But it is possible to build the IL for the delegate at runtime if you want to. What you do is persist the body of the predicate as an expression tree. At runtime the expression tree can dynamically compile itself into brand-new IL; basically we start up a very simplified compiler that knows how to generate IL for expression trees. That way you can change the details of the predicate at runtime and recompile the predicate without having to recompile the whole program.
The author of that comment is using “baking” as a slang for “dynamic lightweight code generation”.