我正在进行一个动态实例化类的自动化工作。
我决定编写一个表达式树来生成一个
从我了解的表达式树和调用函数的知识来看,性能差异应该几乎不存在(也许只有20-30%,但绝不是3倍之多)。
首先,这是我构建的表达式。
我接下来会这样编译它(我只需要这样做一次)。
然后我像这样调用我的Func函数
当我将这个最后部分放入循环中并与类似的内容进行比较时。
如您所见,我的
*对于任何想要测试此代码的人,请查看我的设置: https://pastebin.com/yvMLqZ2t
我决定编写一个表达式树来生成一个
Func
,以便能够为我实例化我的类。然而,我注意到使用Func
比简单地使用new
要慢3倍。从我了解的表达式树和调用函数的知识来看,性能差异应该几乎不存在(也许只有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);
}
我接下来会这样编译它(我只需要这样做一次)。
var c1 = mapper.BuildLambda<Class1, int>("Id").Compile();
然后我像这样调用我的Func函数
var result = c1.Invoke(5);
当我将这个最后部分放入循环中并与类似的内容进行比较时。
var result = new Class1() { Id = 5 };
我进行了一些测试,比较了两者的性能,以下是我的结论:
100,000 Iterations - new: 0ms. | Func 2ms.
600,000 Iterations - new: 5ms. | Func 14ms.
3,100,000 Iterations - new: 24ms. | Func 74ms.
15,600,000 Iterations - new: 118ms. | Func 378ms.
78,100,000 Iterations - new: 597ms. | Func 1767ms.
如您所见,我的
Func.Invoke()
大约比使用 new
实例化慢2.5-3倍。 有没有人有什么提示可以帮助我改进这个问题?(我不介意使用纯反射,因为我能够获得更好的性能)*对于任何想要测试此代码的人,请查看我的设置: https://pastebin.com/yvMLqZ2t
[assembly: AllowPartiallyTrustedCallers]
添加到代码中,则两种变体的结果几乎相同(在我的机器上,表达式调用最多慢1.5倍)。该答案还有一个链接指向另一个问题,其中给出了相同的答案。虽然我不确定原因,但如果有人能深入探讨“这似乎有点错误”的原因,我也会非常感激... - Akos Nagy