I have a situation where my C# application with .Net 4 is accessing a static method within a static class making the method perform slower than when accessed by a single thread. Say for example, If the method is called by a single thread it takes around 1.5 minutes to complete, whereas when called by 2 threads it takes 4 minutes to complete.
Any ideas/suggestion/best practices to increase the performance is highly appreciated. Thanks in advance for your responses.
Some more info:
This is an application which was using threadpool earlier to perform threading in some parts. I introduced parallel tasks. Hence it’s a mix up of TPL and older Thread pool. Say for example one parallel task can have multiple threads. The machine has 24 CPU cores with 64GB RAM. I ran 2 processes which would have split to 5 threads each totalling upto 10 threads. During this the process got slower. I am pasting the code here for those who would like to inspect it and provide suggestions. Sorry for pasting long code. The code may not be having all current latest features as this was coded few years ago. Thanks once again.
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
There is nothing intrinsic about a static method that would make it slower when accessed by multiple threads, unless for example:
lock, or going to a single UI threadSince you haven’t posted any code, we can only guess.