C# 在创建委托时缺少性能

C# 在创建委托时缺少性能,c#,performance,linq,lambda,C#,Performance,Linq,Lambda,我有一个具有存储库模式的应用程序。它允许我通过LINQ操作对象,对象存储在内存中,所以我可以非常快速地访问它们。下面是一个示例代码: private Measurement ParseExact(AgentParameter agentParameter) { ControlledElement ce; using (var repositoryBase = Datastore.GetRepository<ControlledElement>()) {

我有一个具有存储库模式的应用程序。它允许我通过LINQ操作对象,对象存储在内存中,所以我可以非常快速地访问它们。下面是一个示例代码:

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
时创建一次闭包。不过,我没有可靠的资源来支持这一点。