嵌套forEach循环导致的性能影响达到4级

时间:2016-04-21 09:23:32

标签: c# performance foreach nested

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

因此,对于当前文件,我有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;
    }

1 个答案:

答案 0 :(得分:0)

如果条目的顺序无关紧要,因为每个嵌套循环的结果都不需要具有foreach源所具有的结构。

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

因为所有数据操作都应该相同,所以将所有foreach重写为并行。将结果保存到ConcurrentDictionary之类的集合中