由于嵌套 forEach 循环最多 4 个级别而导致的性能影响

本文关键字:影响 性能 于嵌套 嵌套 循环 forEach | 更新日期: 2024-10-31 17:01:46

我有一个非常独特的情况,我正在生成一个文件,我必须为此使用嵌套循环。

因此,对于当前文件,我有 4 个级别的嵌套 foreach ()。 当数据较少时,其性能还可以,OK类型仍然不好,但是当数据开始增长时,由于嵌套,循环呈指数级增长。

因此,这需要花费大量时间。请向我建议一些替代方案,或者如何优化我的代码。

用例:我尝试打印的文件说具有这些嵌套循环的结构的蓝图,所以我不得不使用嵌套.

例如:


Member Details (Level 1)
    Health Coverage (Level 2)
      Provider Information (Level 3)
        BeneFits (Level 4)

因此,会员详细信息可以有多个健康保险,其中每个健康保险可以有多个提供者

,其中每个提供者可以有多个福利。

希望这对我的情况有所帮助 在实时示例中

Level1
foreach()
{
//do some stuff
//writer.writeline();
    level2
    foreach()
    {
      //do some stuff
      //writer.writeline();
      level3
      foreach()
      {
        //do some stuff
        //writer.writeline();
        level4
         foreach()
         {
          //do some stuff
          //writer.writeline();
         }
      }
   }
}

法典

在下面使用的方法中 writeWholeLine() ,它再次为每个循环包含 3 个嵌套,由于正文字符的限制,无法在此处发布代码


  private string TransactionsGeneration(StreamWriter writer, string line, int maximumCount)
    {
        #region Re-Generation
        TransactionCounter = 0;
        foreach (DataRow memRow in MemberTblMaster.Rows)
        {
            TransactionCounter++;
            line = string.Empty; //begin of a new Transaction
            //Counter
            TotalLines = 0;
            ST_SE_UniqueCode = 0;

            // Fill the dataset based on the member id
            MemberID = Convert.ToString(memRow[MEMBER_ID]).Trim();
            HealthCoverageTbl = HealthCoverageTblMaster.AsEnumerable().Where(x => x.Field<string>(MEMBER_ID).Trim() == MemberID);
            Associations834Tbl = Associations834TblMaster.AsEnumerable().Where(x => x.Field<string>(MEMBER_ID).Trim() == MemberID);
            AddressTbl = AddressTblMaster.AsEnumerable().Where(x => x.Field<string>(MEMBER_ID).Trim() == MemberID);
            GenNameInfoTbl = GenNameInfoTblMaster.AsEnumerable().Where(x => x.Field<string>(Gen_Name_ID).Trim() == memRow[Sponsor_ID].ToString().Trim() ||
                                                                    x.Field<string>(Gen_Name_ID).Trim() == memRow[Payer_ID].ToString().Trim() ||
                                                                    x.Field<string>(Gen_Name_ID).Trim() == memRow[TPA_Broker_ID].ToString().Trim()
                                                                    );
            ContactTbl = ContactTblMaster.AsEnumerable().Where(x => x.Field<string>(MEMBER_ID).Trim() == MemberID);
            GenReferenceTbl = GenReferenceTblMaster.AsEnumerable().Where(x => x.Field<string>(MEMBER_ID).Trim() == MemberID);
            MemberTbl = MemberTblMaster.AsEnumerable().Where(x => x.Field<string>(MEMBER_ID).Trim() == MemberID);

            // Based on Health Coverage
            //Provider , COB

            var loopLevel1 = (from row in LoopOrder.AsEnumerable()
                              where row.Field<int>(HIERARCHY_LEVEL) == 1
                              && !Header.Contains(row.Field<string>(LOOP_ID).Trim())
                              && !Footer.Contains(row.Field<string>(LOOP_ID).Trim())
                              select row);
            foreach (DataRow parentLoop in loopLevel1)
            {
                //Level 1
                //TODO : Need to implement the parent loop functionality
                ParentLoop = Convert.ToString(parentLoop[PARENT_LOOP]);
                string loopIDofLoopOrder = parentLoop[LOOP_ID].ToString();
                LoopID = loopIDofLoopOrder;
                var resultLevel1 = (from row in ValidationElementAttribute.AsEnumerable()
                                    where row.Field<string>(LoopIdSegment).Trim() == loopIDofLoopOrder
                                    select row);
                if (resultLevel1.Any())
                {
                    int maxCount1;
                    if (String.IsNullOrEmpty(Convert.ToString(parentLoop[Repeat_max])))
                        maxCount1 = maximumCount; //Max_Repitition = NULL means infinite number of repititions allowed; no upper cap
                    else
                        maxCount1 = Convert.ToInt32(parentLoop[Repeat_max]);
                    for (int i = 0; i < maxCount1; i++) //until all the repititions are covered, keep repeating the same loop, else change the parent loop
                    {
                        SkipLine = false;
                        WriteWholeLine(line, i, resultLevel1, writer, memRow);

                        #region Level 2
                        var loopLevel2 = (from row in LoopOrder.AsEnumerable()
                                          where row.Field<int>(HIERARCHY_LEVEL) == 2
                                          && row.Field<string>(PARENT_LOOP).Trim() == loopIDofLoopOrder.Trim()
                                          select row);
                        foreach (DataRow level2 in loopLevel2)
                        {
                            //Level 2
                            //  ChildLoop = Convert.ToString(level2["PARENT_LOOP"]);// 1000C
                            ChildLoop = Convert.ToString(level2[LOOP_ID]);// 1100C
                            LoopID = ChildLoop;
                            var resultLevel2 = (from row in ValidationElementAttribute.AsEnumerable()
                                                where row.Field<string>(LoopIdSegment).Trim() == ChildLoop.Trim()
                                                select row);
                            //var healthCoverageIdList = memberEnrollment.Select(x => x.Field<object>(Health_Coverage_ID)).Distinct().ToList();
                            if (resultLevel2.Any())
                            {
                                int maxCount2;
                                if (String.IsNullOrEmpty(Convert.ToString(level2[Repeat_max])))
                                    maxCount2 = maximumCount;
                                else
                                    maxCount2 = Convert.ToInt32(level2[Repeat_max]);
                                //Custom Code                                   
                                // maxCount2=  ChildLoop == _2300 ?  healthCoverageIdList.Count :  maxCount2;

                                for (int j = 0; j < maxCount2; j++)
                                {
                                    SkipLine = false;
                                    //Custom Code
                                    //if (ChildLoop == "2300")
                                    //{
                                    //    WriteWholeLine(line, j, resultLevel2, writer, memRow, memberEnrollment.Where(x => x.Field<object>(Health_Coverage_ID) == healthCoverageIdList[j]).Select(x => x));
                                    //}
                                    //else
                                    //{
                                    //WriteWholeLine(line, j, resultLevel2, writer, memRow, memberEnrollment);
                                    //}

                                    WriteWholeLine(line, j, resultLevel2, writer, memRow);
                                    if (HealthCoverageTbl.Any() && HealthCoverageTbl.Count() > j)
                                    {
                                        HealthCoverageID = Convert.ToString(HealthCoverageTbl.ElementAt(j).Field<string>(Health_Coverage_ID)).Trim();
                                    }
                                    else
                                    {
                                        HealthCoverageID = string.Empty;
                                    }
                                    #region Level 3

                                    var loopLevel3 = (from row in LoopOrder.AsEnumerable()
                                                      where row.Field<int>(HIERARCHY_LEVEL) == 3
                                                      && row.Field<string>(PARENT_LOOP).Trim() == ChildLoop.Trim()
                                                      select row);
                                    foreach (DataRow level3 in loopLevel3)
                                    {
                                        //Level 3
                                        ChildLoopLevel3 = Convert.ToString(level3[LOOP_ID]);
                                        LoopID = ChildLoopLevel3;
                                        var resultLevel3 = (from row in ValidationElementAttribute.AsEnumerable()
                                                            where row.Field<string>(LoopIdSegment).Trim() == ChildLoopLevel3.Trim()
                                                            select row);
                                        if (resultLevel3.Any())
                                        {
                                            CobInfoTbl = CobInfoTblMaster.AsEnumerable().Where(x => x.Field<string>(Health_Coverage_ID).Trim() == HealthCoverageID).Select(x => x);
                                            ProviderTbl = ProviderTblMaster.AsEnumerable().Where(x => x.Field<string>(Health_Coverage_ID).Trim() == HealthCoverageID).Select(x => x);
                                            LXcounter = 0;
                                            int maxCount3;
                                            if (String.IsNullOrEmpty(Convert.ToString(level3[Repeat_max])))
                                                maxCount3 = maximumCount;
                                            else
                                                maxCount3 = Convert.ToInt32(level3[Repeat_max]);
                                            for (int k = 0; k < maxCount3; k++)
                                            {
                                                SkipLine = false;
                                                if (CobInfoTbl.Any() && CobInfoTbl.Count() > k)
                                                {
                                                    CobInfoID = CobInfoTbl.ElementAt(k).Field<string>(COB_ID);
                                                }
                                                else
                                                {
                                                    CobInfoID = Convert.ToString("0");
                                                }
                                                //Not used : uncomment if Provider ID needed.
                                                if (ProviderTbl.Any() && ProviderTbl.Count() > k)
                                                {
                                                    ProviderID = ProviderTbl.ElementAt(k).Field<string>(Provider_ID).Trim();
                                                }
                                                else
                                                {
                                                    ProviderID = string.Empty;
                                                }
                                                WriteWholeLine(line, k, resultLevel3, writer, memRow);

                                                #region Level 4
                                                var loopLevel4 = (from row in LoopOrder.AsEnumerable()
                                                                  where row.Field<int>(HIERARCHY_LEVEL) == 4
                                                                  && row.Field<string>(PARENT_LOOP).Trim() == ChildLoopLevel3.Trim()
                                                                  select row);
                                                foreach (DataRow level4 in loopLevel4)
                                                {
                                                    //Level 4
                                                    ChildLoopLevel4 = Convert.ToString(level4[LOOP_ID]);
                                                    LoopID = ChildLoopLevel4;
                                                    var resultLevel4 = (from row in ValidationElementAttribute.AsEnumerable()
                                                                        where row.Field<string>(LoopIdSegment).Trim() == ChildLoopLevel4.Trim()
                                                                        select row);
                                                    if (resultLevel4.Any())
                                                    {
                                                        int maxCount4;
                                                        if (String.IsNullOrEmpty(Convert.ToString(level4[Repeat_max])))
                                                            maxCount4 = maximumCount;
                                                        else
                                                            maxCount4 = Convert.ToInt32(level4[Repeat_max]);
                                                        for (int l = 0; l < maxCount4; l++)
                                                        {
                                                            SkipLine = false;
                                                            WriteWholeLine(line, l, resultLevel4, writer, memRow);
                                                        }
                                                    }
                                                }
                                                #endregion
                                            }
                                        }
                                    }
                                    #endregion
                                }
                            }
                        }
                        #endregion
                    }
                }
            }
            // TODO : remove below break
            // break;
        }
        //end of Regeneration
        #endregion
        return line;
    }

由于嵌套 forEach 循环最多 4 个级别而导致的性能影响

如果条目的顺序无关紧要,就像在每个嵌套循环的结果中一样,则不需要具有foreach源具有的结构。

A->B->C->D->E 每个都代表一个嵌套循环,您可以并行执行。

由于所有数据操作都应该相同,因此请以并行方式重写所有 foreach。 将结果保存到集合中,如 ConcurrentDictionary