Foreach语句耗时太长

本文关键字:语句 Foreach | 更新日期: 2023-09-27 18:13:09

我有一个foreach语句在另一个foreach语句中,这需要很长时间来迭代。(有很多记录)。有没有一种方法可以简化这段代码?也许和Linq一起?下面是我的代码:

IList<SourceCounterPartyExposure_Limit> exposures = new List<SourceCounterPartyExposure_Limit>();
foreach (SourceCounterParty counterParty in limit.SourceCounterParties)
{
    foreach (SourceCounterPartyExposure_Limit exposure in counterParty.LimitExposures)
    {
        if (!exposures.Contains(exposure))
        {
            arExposures += exposure.ARExposure;
            mtmExposures += exposure.MTMExposure;
            volumeExposures += exposure.ConvertedVolume;
            if (maxTenorExposures < exposure.MaxTenor) 
             {maxTenorExposures = exposure.MaxTenor; }
            exposures.Add(exposure);
        } // if
    } // foreach
}// foreach

Foreach语句耗时太长

当然可以简化代码:

IEnumerable<Exposure> exposures = 
  limit.SourceCounterParties.SelectMany(e => e.LimitExposures).Distinct()

折叠循环和if语句。你可以在上面加foreach,然后运行你的代码:

foreach (Exposure exposure in exposures)
{
    arExposures += exposure.ARExposure;
    mtmExposures += exposure.MTMExposure;
    volumeExposures += exposure.ConvertedVolume;
    if (maxTenorExposures < exposure.MaxTenor) 
       {maxTenorExposures = exposure.MaxTenor; 
}

话虽如此,它仍然是一个很大的枚举,在这里您不会获得的速度。

尝试单次循环:

limit.SourceCounterParties.SelectMany(x => x.LimitExposures).Distinct()

这样你就(i)只从数据库中得到不同的记录,(ii)允许实体框架将你的查询转换成在数据库上执行的东西。

您也可以使用SumMax来创建将在数据库上执行的单个查询。

导致代码运行缓慢的一个可能原因是:

if (!exposures.Contains(exposure))

如果最终订单或项目不重要,或者您可以稍后对它们进行排序,我建议您将其替换为

var exposures = new HashSet<SourceCounterPartyExposure_Limit> ();

如果SourceCounterPartyExposure_Limit类具有良好的散列函数,那么搜索应该很快(接近0(1)),并且它可能会大大提高代码的整体性能。

也可能你可以改变算法在多线程中运行,然后合并结果。但我不确定这是否适合你。