我正在生成一个表达式树,它将属性从源对象映射到目标对象,然后编译为a Func<TSource, TDestination, TDestination>并执行.
这是结果的调试视图LambdaExpression:
.Lambda #Lambda1<System.Func`3[MemberMapper.Benchmarks.Program+ComplexSourceType,MemberMapper.Benchmarks.Program+ComplexDestinationType,MemberMapper.Benchmarks.Program+ComplexDestinationType]>(
MemberMapper.Benchmarks.Program+ComplexSourceType $right,
MemberMapper.Benchmarks.Program+ComplexDestinationType $left) {
.Block(
MemberMapper.Benchmarks.Program+NestedSourceType $Complex$955332131,
MemberMapper.Benchmarks.Program+NestedDestinationType $Complex$2105709326) {
$left.ID = $right.ID;
$Complex$955332131 = $right.Complex;
$Complex$2105709326 = .New MemberMapper.Benchmarks.Program+NestedDestinationType();
$Complex$2105709326.ID = $Complex$955332131.ID;
$Complex$2105709326.Name = $Complex$955332131.Name;
$left.Complex = $Complex$2105709326;
$left
}
}
Run Code Online (Sandbox Code Playgroud)
清理它将是:
(left, right) =>
{
left.ID = right.ID;
var complexSource = right.Complex;
var complexDestination = new NestedDestinationType();
complexDestination.ID = complexSource.ID;
complexDestination.Name = complexSource.Name;
left.Complex = complexDestination;
return left;
}
Run Code Online (Sandbox Code Playgroud)
这是映射这些类型的属性的代码:
public class NestedSourceType
{
public int ID …Run Code Online (Sandbox Code Playgroud) 我正在研究动态实例化类的自动化.
我决定写一个表达式树,它会生成一个Func,可以为我实例化我的类.但是,我注意到我的性能降低了3倍Func,而不是简单地使用new.
根据我对表达树和调用函数的了解,性能差异应该几乎不存在(可能是20-30%,但远不及慢3倍)
首先,这是我正在构建的表达式
public Expression<Func<A1, T>> BuildLambda<T, A1>(string param1Name)
{
var createdType = typeof(T);
var param = Expression.Parameter(typeof(A1), param1Name);
var ctor = Expression.New(createdType);
var prop = createdType.GetProperty(param1Name);
var displayValueAssignment = Expression.Bind(prop, param);
var memberInit = Expression.MemberInit(ctor, displayValueAssignment);
return
Expression.Lambda<Func<A1, T>>(memberInit, param);
}
Run Code Online (Sandbox Code Playgroud)
然后我继续编译它(我只做一次)
var c1 = mapper.BuildLambda<Class1, int>("Id").Compile();
Run Code Online (Sandbox Code Playgroud)
然后我像这样调用我的Func
var result = c1.Invoke(5);
Run Code Online (Sandbox Code Playgroud)
当我把这最后一部分放在一个循环中并将它与类似的东西进行比较时
var result = new Class1() { Id = 5 };
Run Code Online (Sandbox Code Playgroud)
我做了几个测试,比较两者的性能,这就是我最终得到的结果:
100,000 Iterations - new: 0ms. | Func 2ms. …Run Code Online (Sandbox Code Playgroud)