2012-06-07 32 views
1

我遇到这样一种情况:我的C#应用​​程序使用.Net 4访问静态类中的静态方法,使得该方法的执行速度比单个线程访问时慢。例如,如果方法被单个线程调用,则需要大约1.5分钟才能完成,而当由2个线程调用时,需要4分钟才能完成。当多线程访问时静态方法变慢

任何想法/建议/最佳实践,以提高性能高度赞赏。预先感谢您的回复。

更多信息: 这是一个早期使用线程池来在某些部分执行线程的应用程序。我介绍了并行任务。因此它是TPL和较老的线程池的混合。比如说一个并行任务可以有多个线程。该机器有24个CPU内核和64GB RAM。我跑了2个进程,这个进程可以分成5个线程,每个进程总共可以有10个线程。在此过程中变得更慢。我在这里粘贴代码,供那些想要检查它并提供建议的人使用。抱歉粘贴长码。该代码可能不会具有当前最新的功能,因为这是几年前编写的。再次感谢。

public static class Property11 
{ 
    /// <summary> 
    /// Splits agg rows to separate commands where the reference parameters are included for each command. 
    /// </summary> 
    /// <param name="worksheetID">The current worksheet ID.</param> 
    /// <param name="propertyID">The current property ID.</param> 
    /// <param name="ccrFormObj">The ccr form object.</param> 
    public static void SplitAggregateIncludeReferenceParameterCCRToDTH(PropertyCall propertyCallObj) 
    { 
     string worksheetID = propertyCallObj.WorksheetID; 
     int propertyID = propertyCallObj.PropertyID; 
     IDClass nextIDObj = propertyCallObj.NextIDObj; 
     CCRFormStructure ccrFormObj = propertyCallObj.CCRFormObj; 
     List<CCRFormStructure> ccrFormObjsToAdd = propertyCallObj.CCRFormObjToAddList; 

     DateTime dtProp = DateTime.Now; 
     System.Diagnostics.Debug.Print("Start time property = " + propertyCallObj.PropertyID + ", worksheet = " + propertyCallObj.WorksheetID + ": " + dtProp.ToString()); 

     try 
     { 
      // Get all rows for worksheet 
      List<WorksheetRow> rowListForWorksheet = 
       (from wr in ccrFormObj.myWorksheetRowList 
       where wr.WorksheetID == worksheetID 
       select wr).ToList(); 

      // Get all parameters for worksheet 
      List<WorksheetRowParameter> rowParameterListForWorksheet = 
       (from wrp in ccrFormObj.myWorksheetRowParameterList 
       join wr in rowListForWorksheet 
       on wrp.WorksheetRowID equals wr.ID 
       select wrp).ToList(); 

      // Get all agg rows in worksheet 
      List<AggRow> aggRowsInWorksheet = 
       (from ar in ccrFormObj.myAggRowList 
       join wsrp in rowParameterListForWorksheet 
       on ar.WorksheetRowParameterID equals wsrp.ID 
       select ar).ToList(); 

      // Get all agg row parameters in worksheet 
      List<AggRowParameter> aggParametersInWorksheet = 
       (from arp in ccrFormObj.myAggRowParameterList 
       join ar in aggRowsInWorksheet 
       on arp.AggRowID equals ar.ID 
       select arp).ToList(); 

      // Get all command mappings for worksheet 
      List<CommandMappingObj> commandMappingListForWorksheet = 
       (from cm in ccrFormObj.commandMappingList 
       join wr in rowListForWorksheet 
       on cm.WorksheetRowID equals wr.ID 
       select cm).ToList(); 

      // Get all parameter mappings for worksheet 
      List<ParameterMappingObj> parameterMappingListForWorksheet = 
       (from pm in ccrFormObj.parameterMappingList 
       join cm in commandMappingListForWorksheet 
       on pm.CommandMappingObjID equals cm.ID 
       select pm).ToList(); 

      // Get all property objects for worksheet 
      List<ParameterPropertyObj> propertyList = 
       (from ppo in ccrFormObj.parameterPropertiesList 
       where ppo.ID == propertyID && ppo.WorksheetID == worksheetID 
       select ppo).ToList(); 

      //List<WorksheetRow> rowsToRemove = new List<WorksheetRow>(); 
      WorksheetRowParameter currentWorksheetRowParameter; 
      AggRow currentAggRow; 
      AggRowParameter currentAggRowParameter; 
      AggRow currentSteeringAggRow; 
      AggRowParameter currentSteeringAggRowParameter; 
      int newIDIndex = 0; 
      List<string> worksheetRowsWithoutTooLongCommandRows = new List<string>(); 
      WorksheetRow newWSR = new WorksheetRow(); 
      CommandMappingObj newCMO = new CommandMappingObj(); 
      WorksheetRow newWSRForOrigRow = new WorksheetRow(); 
      CommandMappingObj newChangeCMO = new CommandMappingObj(); 
      List<string> steeringParameters; 
      IEnumerable<WorksheetRowParameter> parameterListForRow; 
      IEnumerable<WorksheetRowParameter> currentSteeringParameters; 
      string newCMOID; 
      ParameterMappingObj newPMO; 
      WorksheetRowParameter newWSRP; 
      string newWSRID; 
      string newID; 
      IEnumerable<string> commandsWithPropertyParameterForRow; 
      Hashtable htPropertyParamAndSteeringParameters = new Hashtable(); 
      List<string> steeringParametersForProperty; 
      WorksheetRowParameter currentWorksheetRowPropertyParameter; 
      bool removeOrigRow = false; 
      bool firstRowForAggCreated = false; 
      List<WorksheetRowParameter> propParamListForFirstCreatedRow = new List<WorksheetRowParameter>(); 
      List<string> propParamUsedAsSteeringList = new List<string>(); 

      foreach (ParameterPropertyObj propertyParameter in propertyList) 
      { 
       if (propertyParameter.SecondaryPropertyInfo != null && propertyParameter.SecondaryPropertyInfo != "") 
       { 
        steeringParameters = propertyParameter.SecondaryPropertyInfo.Split(",".ToCharArray()).ToList(); 
       } 
       else 
       { 
        steeringParameters = new List<string>(); 
       } 

       htPropertyParamAndSteeringParameters.Add(propertyParameter.Parameter, steeringParameters); 
      } 

      var aggListForRow = 
       from ar in aggRowsInWorksheet 
       join arp in aggParametersInWorksheet 
       on ar.ID equals arp.AggRowID 
       select new 
       { 
        AggRow = ar, 
        AggRowParameter = arp 
       }; 

      var worksheetRowsWithRepParam = 
       from wrp in rowParameterListForWorksheet 
       where htPropertyParamAndSteeringParameters.Contains(wrp.Parameter) 
       join al in aggListForRow 
       on wrp.ID equals al.AggRow.WorksheetRowParameterID 
       into aggList 
       where aggList.Count() > 0 
       select new 
       { 
        WorksheetRowParameter = wrp, 
        AggList = aggList 
       }; 

      foreach (WorksheetRow worksheetRow in rowListForWorksheet.ToList()) 
      { 
       var worksheetRowWithRepParam = 
        worksheetRowsWithRepParam.Where(wrp => wrp.WorksheetRowParameter.WorksheetRowID == worksheetRow.ID); 

       if (worksheetRowWithRepParam.Count() > 0) 
       { 
        firstRowForAggCreated = false; 

        var currentMappingList = 
         from cmo in commandMappingListForWorksheet 
         where cmo.WorksheetRowID == worksheetRow.ID 
         join pmo in parameterMappingListForWorksheet 
         on cmo.ID equals pmo.CommandMappingObjID 
         into parameterMappingList 
         select new 
         { 
          CommandMapping = cmo, 
          ParameterMappingList = parameterMappingList 
         }; 

        IEnumerable<ParameterPropertyObj> sortedPropertyList = 
         from wrwrp in worksheetRowWithRepParam 
         join ppo in propertyList 
         on wrwrp.WorksheetRowParameter.Parameter equals ppo.Parameter 
         orderby wrwrp.AggList.Count() descending 
         select ppo; 

        propParamUsedAsSteeringList.Clear(); 

        foreach (ParameterPropertyObj ppo in sortedPropertyList) 
        { 
         if (!propParamUsedAsSteeringList.Contains(ppo.Parameter)) 
         { 
          var currentWorksheetRowsWithRepParam = 
           worksheetRowWithRepParam.Where(p => p.WorksheetRowParameter.Parameter == ppo.Parameter); 

          if (currentWorksheetRowsWithRepParam.Count() == 0) 
          { 
           continue; 
          } 

          var currentWorksheetRowWithRepParam = currentWorksheetRowsWithRepParam.ElementAt(0); 

          var currentAggList = currentWorksheetRowWithRepParam.AggList; 

          if (!firstRowForAggCreated) 
          { 
           currentWorksheetRowPropertyParameter = currentWorksheetRowWithRepParam.WorksheetRowParameter; 
          } 
          else 
          { 
           currentWorksheetRowPropertyParameter = propParamListForFirstCreatedRow.Where(p => p.Parameter == ppo.Parameter).ElementAt(0); 
          } 

          if (currentAggList.Count() > 1) 
          { 
           removeOrigRow = true; 

           steeringParametersForProperty = (List<string>)htPropertyParamAndSteeringParameters[ppo.Parameter]; 

           currentSteeringParameters = 
            from wrp in rowParameterListForWorksheet 
            where wrp.WorksheetRowID == worksheetRow.ID 
            && steeringParametersForProperty.Contains(wrp.Parameter) 
            select wrp; 

           commandsWithPropertyParameterForRow = 
            from cml in currentMappingList 
            where cml.ParameterMappingList.Count(pmo => pmo.Name == ppo.Parameter) > 0 
            select cml.CommandMapping.Name; 

           propParamUsedAsSteeringList.AddRange(
            from sp in sortedPropertyList 
            where sp.Parameter != ppo.Parameter 
            join csp in currentSteeringParameters 
            on sp.Parameter equals csp.Parameter 
            select csp.Parameter); 

           // CREATE NEW WORKSHEET ROWS FOR EACH BUT THE FIRST AGG ROW PARAMETER 
           for (int i = 0; i < currentAggList.Count(); i++) 
           { 
            currentAggRow = currentAggList.ElementAt(i).AggRow; 
            currentAggRowParameter = currentAggList.ElementAt(i).AggRowParameter; 

            if (i == 0) 
            { 
             currentWorksheetRowPropertyParameter.Value = currentAggRowParameter.Value; 

             if (!firstRowForAggCreated) 
             { 
              propParamListForFirstCreatedRow.Clear(); 

              newWSRID = newIDIndex.ToString().PadLeft(3, '0'); 
              newID = newWSRID; 

              if (!worksheetRow.ID.Contains(',')) 
              { 
               newID = "," + newWSRID; 
              } 

              newWSRForOrigRow = new WorksheetRow 
              { 
               ID = worksheetRow.ID + newID, 
               OriginalWorksheetRowID = worksheetRow.OriginalWorksheetRowID, 
               WorksheetID = worksheetRow.WorksheetID 
              }; 

              ccrFormObj.myWorksheetRowList.Add(newWSRForOrigRow); 

              parameterListForRow = 
               from wrp in rowParameterListForWorksheet 
               where wrp.WorksheetRowID == worksheetRow.ID 
               select wrp; 

              foreach (WorksheetRowParameter currentParameter in parameterListForRow) 
              { 
               newID = ""; 

               if ((currentParameter.ID != null) && (!currentParameter.ID.Contains(','))) 
               { 
                newID = ","; 
               } 

               newID += newIDIndex.ToString().PadLeft(3, '0'); 

               newWSRP = new WorksheetRowParameter 
               { 
                ID = currentParameter.ID + newID, 
                OriginalParameterID = currentParameter.OriginalParameterID, 
                WorksheetRowID = newWSRForOrigRow.ID, 
                Parameter = currentParameter.Parameter, 
                Value = currentParameter.Value, 
                Disabled = currentParameter.Disabled 
               }; 

               if (htPropertyParamAndSteeringParameters.Contains(newWSRP.Parameter) 
                && newWSRP.Parameter != ppo.Parameter) 
               { 
                // TODO: IF AGG, TAKE AGG POS VALUE 

                var steeringParamAggList = 
                 from wrwrp in worksheetRowWithRepParam 
                 where wrwrp.WorksheetRowParameter.Parameter == newWSRP.Parameter 
                 select wrwrp.AggList; 

                if (steeringParamAggList.Count() > 0) 
                { 
                 if (steeringParamAggList.ElementAt(0).Count() > i) 
                 { 
                  currentSteeringAggRow = steeringParamAggList.ElementAt(0).ElementAt(i).AggRow; 
                  currentSteeringAggRowParameter = steeringParamAggList.ElementAt(0).ElementAt(i).AggRowParameter; 

                  newWSRP.Value = currentSteeringAggRowParameter.Value; 

                  ccrFormObj.myAggRowParameterList.Remove(currentSteeringAggRowParameter); 
                  ccrFormObj.myAggRowList.Remove(currentSteeringAggRow); 

                  ccrFormObj.myWorksheetRowParameterList.Add(newWSRP); 
                 } 
                } 
                else 
                { 
                 ccrFormObj.myWorksheetRowParameterList.Add(newWSRP); 
                } 

                propParamListForFirstCreatedRow.Add(newWSRP); 
               } 
               else 
               { 
                ccrFormObj.myWorksheetRowParameterList.Add(newWSRP); 
               } 
              } 

              foreach (var currentMapping in currentMappingList) 
              { 
               // Re-point original command mapping to new row 
               newCMOID = newIDIndex.ToString().PadLeft(3, '0'); 

               if (!currentMapping.CommandMapping.ID.Contains(',')) 
               { 
                newID = "," + newCMOID; 
               } 

               // Create new command mapping object 
               newCMO = new CommandMappingObj 
               { 
                ID = currentMapping.CommandMapping.ID + newID, 
                Name = currentMapping.CommandMapping.Name, 
                WorksheetRowID = newWSRForOrigRow.ID 
               }; 

               ccrFormObj.commandMappingList.Add(newCMO); 

               foreach (ParameterMappingObj pmo in currentMapping.ParameterMappingList) 
               { 
                newPMO = new ParameterMappingObj 
                { 
                 Name = pmo.Name, 
                 CommandMappingObjID = newCMO.ID 
                }; 

                ccrFormObj.parameterMappingList.Add(newPMO); 
               } 
              } 

              firstRowForAggCreated = true; 
             } 
            } 
            else 
            { 
             newWSRID = newIDIndex.ToString().PadLeft(3, '0'); 
             newID = newWSRID; 

             if (!worksheetRow.ID.Contains(',')) 
             { 
              newID = "," + newWSRID; 
             } 

             newWSR = new WorksheetRow 
             { 
              ID = worksheetRow.ID + newID, 
              OriginalWorksheetRowID = worksheetRow.OriginalWorksheetRowID, 
              WorksheetID = worksheetRow.WorksheetID 
             }; 

             ccrFormObj.myWorksheetRowList.Add(newWSR); 

             foreach (WorksheetRowParameter currentSteeringParameter in currentSteeringParameters) 
             { 
              newID = ""; 

              if ((currentSteeringParameter.ID != null) && (!currentSteeringParameter.ID.Contains(','))) 
              { 
               newID = ","; 
              } 

              newID += newIDIndex.ToString().PadLeft(3, '0'); 

              newWSRP = new WorksheetRowParameter 
              { 
               ID = currentSteeringParameter.ID + newID, 
               OriginalParameterID = currentSteeringParameter.OriginalParameterID, 
               WorksheetRowID = newWSR.ID, 
               Parameter = currentSteeringParameter.Parameter, 
               Value = currentSteeringParameter.Value, 
               Disabled = currentSteeringParameter.Disabled 
              }; 

              var steeringParamAggList = 
               from wrwrp in worksheetRowWithRepParam 
               where wrwrp.WorksheetRowParameter.Parameter == newWSRP.Parameter 
               select wrwrp.AggList; 

              if (steeringParamAggList.Count() > 0) 
              { 
               if (steeringParamAggList.ElementAt(0).Count() > i) 
               { 
                currentSteeringAggRow = steeringParamAggList.ElementAt(0).ElementAt(i).AggRow; 
                currentSteeringAggRowParameter = steeringParamAggList.ElementAt(0).ElementAt(i).AggRowParameter; 

                newWSRP.Value = currentSteeringAggRowParameter.Value; 

                ccrFormObj.myAggRowParameterList.Remove(currentSteeringAggRowParameter); 
                ccrFormObj.myAggRowList.Remove(currentSteeringAggRow); 

                ccrFormObj.myWorksheetRowParameterList.Add(newWSRP); 
               } 
              } 
              else 
              { 
               ccrFormObj.myWorksheetRowParameterList.Add(newWSRP); 
              } 
             } 

             // Add rep param 
             newID = ""; 

             if ((currentWorksheetRowPropertyParameter.ID != null) && (!currentWorksheetRowPropertyParameter.ID.Contains(','))) 
             { 
              newID = ","; 
             } 

             newID += newIDIndex.ToString().PadLeft(3, '0'); 

             newWSRP = new WorksheetRowParameter 
             { 
              ID = currentWorksheetRowPropertyParameter.ID + newID, 
              OriginalParameterID = currentWorksheetRowPropertyParameter.OriginalParameterID, 
              WorksheetRowID = newWSR.ID, 
              Parameter = currentWorksheetRowPropertyParameter.Parameter, 
              Value = currentAggRowParameter.Value, 
              Disabled = currentWorksheetRowPropertyParameter.Disabled 
             }; 

             ccrFormObj.myWorksheetRowParameterList.Add(newWSRP); 

             foreach (var currentMapping in currentMappingList) 
             { 
              if (commandsWithPropertyParameterForRow.Contains(currentMapping.CommandMapping.Name)) 
              { 
               newCMOID = newIDIndex.ToString().PadLeft(3, '0'); 

               if (!currentMapping.CommandMapping.ID.Contains(',')) 
               { 
                newID = "," + newCMOID; 
               } 

               // Create new command mapping object 
               newCMO = new CommandMappingObj 
               { 
                ID = currentMapping.CommandMapping.ID + newID, 
                Name = currentMapping.CommandMapping.Name, 
                WorksheetRowID = newWSR.ID 
               }; 

               ccrFormObj.commandMappingList.Add(newCMO); 

               foreach (ParameterMappingObj pmo in currentMapping.ParameterMappingList) 
               { 
                if ((pmo.Name == ppo.Parameter) || (currentSteeringParameters.Count(p => p.Parameter == pmo.Name) > 0)) 
                { 
                 newPMO = new ParameterMappingObj 
                 { 
                  Name = pmo.Name, 
                  CommandMappingObjID = newCMO.ID 
                 }; 

                 ccrFormObj.parameterMappingList.Add(newPMO); 
                } 
               } 
              } 
             } 
            } 

            newIDIndex++; 

            ccrFormObj.myAggRowParameterList.Remove(currentAggRowParameter); 
            ccrFormObj.myAggRowList.Remove(currentAggRow); 
           } 
          } 
          else 
          { 
           currentAggRow = currentAggList.ElementAt(0).AggRow; 
           currentAggRowParameter = currentAggList.ElementAt(0).AggRowParameter; 
           currentWorks 
+4

如果没有关于您的代码的具体细节,则无法回答。 *任何*都可能是原因。 – usr

+0

没有看你的方法是没办法告诉你的。可能的答案从糟糕的编码到缓存对齐问题。 – dasblinkenlight

+0

是不是交叉的方法?因为它的静态只有一个实现,所以所有的线程将使用相同的1? - 我真的问 – bresleveloper

回答

5

没有什么内在约一个静态方法,这将使它更慢的时候被多个线程访问,除非例如:

  • 您有被节流一些共享资源,例如作为一个共享的lock,或去一个单一的UI线程
  • 你有更多的线程比可用的CPU核心,它只是不得不做很多切换
  • 你正在最大化som e其他资源,如磁盘IO,网络IO等

由于您还没有发布任何代码,我们只能猜测。