C# 在创建委托时缺少性能
我有一个具有存储库模式的应用程序。它允许我通过LINQ操作对象,对象存储在内存中,所以我可以非常快速地访问它们。下面是一个示例代码:C# 在创建委托时缺少性能,c#,performance,linq,lambda,C#,Performance,Linq,Lambda,我有一个具有存储库模式的应用程序。它允许我通过LINQ操作对象,对象存储在内存中,所以我可以非常快速地访问它们。下面是一个示例代码: private Measurement ParseExact(AgentParameter agentParameter) { ControlledElement ce; using (var repositoryBase = Datastore.GetRepository<ControlledElement>()) {
private Measurement ParseExact(AgentParameter agentParameter)
{
ControlledElement ce;
using (var repositoryBase = Datastore.GetRepository<ControlledElement>())
{
var mvId = Convert.ToInt32(agentParameter.ControlledParameterId);
var sId = Convert.ToInt32(agentParameter.FacilityId);
ce =
repositoryBase.Query(
t => t.FirstOrDefault(elem => elem.Sensor.Id == sId && elem.MeasuringValue.Id == mvId));
}
}
private Measurement ParseExact(AgentParameter AgentParameter)
{
受控元素ce;
使用(var repositoryBase=Datastore.GetRepository())
{
var mvId=Convert.ToInt32(agentParameter.ControlledParameterId);
var sId=Convert.ToInt32(agentParameter.FacilityId);
行政长官=
repositoryBase.Query(
t=>t.FirstOrDefault(elem=>elem.Sensor.Id==sId&&elem.MeasuringValue.Id==mvId));
}
}
当我使用dotTrace分析代码时,我发现在高负载情况下,我在创建委托elem=>elem.Sensor.Id==sId&&elem.MeasuringValue.Id==mvId
时缺乏性能。我的查询方法如下所示:
public TOut Query(Func规范)
这意味着每次使用Func
对象时,我都会传递它。所以,问题是,我如何优化它
编辑创作和编辑方面的不足证明
您可以通过显式跟踪对象中的状态而不是使用闭包来消除编译步骤
private Measurement ParseExact(AgentParameter agentParameter)
{
ControlledElement ce;
using (var repositoryBase = Datastore.GetRepository<ControlledElement>())
{
var mvId = Convert.ToInt32(agentParameter.ControlledParameterId);
var sId = Convert.ToInt32(agentParameter.FacilityId);
var query = new ParseExactQuery(mvId, sId);
ce = repositoryBase.Query(t => t.FirstOrDefault(query.Query));
}
}
private class ParseExactQuery {
private int mvId;
private int sId;
public ParseExactQuery (int mvId, int sId) {
this.mvId = mvId;
this.sId = sId;
}
public bool Query(ControlledElement elem) {
return elem.Sensor.Id == sId && elem.MeasuringValue.Id == mvId;
}
}
private Measurement ParseExact(AgentParameter AgentParameter)
{
受控元素ce;
使用(var repositoryBase=Datastore.GetRepository())
{
var mvId=Convert.ToInt32(agentParameter.ControlledParameterId);
var sId=Convert.ToInt32(agentParameter.FacilityId);
var query=新的ParseExactQuery(mvId,sId);
ce=repositoryBase.Query(t=>t.FirstOrDefault(Query.Query));
}
}
私有类解析查询{
私有int-mvId;
私有int-sId;
公共查询(intmvid,intsid){
this.mvId=mvId;
this.sId=sId;
}
公共布尔查询(ControlleElement元素){
返回elem.Sensor.Id==sId&&elem.MeasuringValue.Id==mvId;
}
}
如果你有一个IQueryable
,你不应该使用表达式吗?如果您真的在使用Func
,这意味着所有数据都在本地获取,然后进行过滤…@JonSkeet我有IQueryable
作为泛化(查询可以在数据库或缓存提供程序中执行)。在这种情况下,也就是在这种情况下,我使用我自己编写的缓存来工作,所以我不知道如何在其中实现表达式。。。我还没有用过它们,也不知道它们是什么。这是我所需要的吗?您是否看到委托创建或委托函数的执行性能不佳?@递归创建和编译。添加图片来证明我的文字这看起来很像为lambda创建的显示类,这不会占用几乎相同的对象创建/垃圾收集时间吗?哇!这给了我很大的鼓舞。我在GC上还有一些开销,但代码工作得更好。多谢各位!无论如何,是否有任何“正确”的方法来处理此类表达式(创建lambda只是为了关闭某些变量?)。我每秒创建这样的lambda将近10000次,我想这不是一个好的实现。我承认我不完全理解为什么这样会更好。我的猜测是,您最初的实现是为每个ControlleElement
重新创建闭包,而此更改仅在每次调用ParseExact
时创建一次闭包。不过,我没有可靠的资源来支持这一点。