I had some code for processing XML file that was running pretty slowly. The offending code is below.
The first query should get either zero or one record from a set of about 1,000 records. If I get one, I then pull from another set (holding about 2,000 records) the needed record using a keyID from the first result. I then take that record, if found, and assign three values to a new object I'm creating.
What I found when checking the performance (execution time) in VS2015 is that all these statements took about 330 ms total. Specifically the assignment of each value (e.g MatProfileCall.MatSizeText = mss.First().MatSizeText;) took around 80 ms each. I then added a .ToArray() to the two queries into vars. The execution went down to less than 40 ms for all the code.
So my question is, in a situation like this, does the assignment of a value from a Linq query that is based on another Linq query actually have to run both queries each time? And if that is true, then does it follow that anytime you are using a query result to assign values to another object there is always a point when putting the result into an array/list is a much better performance because Linq has to execute the query each time?
var subMatSize = (from d in pInEdiMatTransS where d.EdiSystemMaterialString == retString && d.IsMapToMatSizeID == true && d.IsSubstituteMatType == false select d);
if (subMatSize.Any())
{
var mss = (from d in pmss where d.MatSizeID == subMatSize.First().DeafultMatSizeID select d);
if(mss.Any())
{
MatProfileCall.MatSizeText = mss.First().MatSizeText;
MatProfileCall.MatSizeID = mss.First().MatSizeID;
MatProfileCall.MatTypeID = mss.First().MatTypeID;
return Result.Ok<EDIMaterialProFile>(MatProfileCall);
}
else
{ return Result.Fail<EDIMaterialProFile>(THC_Constants.sMICEDICONVERTERROR + "IsMapToMatSizeID is True but MatSizeID not found in MaterialSize"); }
}
Same code with .ToArray() producing a much faster code:
var subMatSize = (from d in pInEdiMatTransS where d.EdiSystemMaterialString == retString && d.IsMapToMatSizeID == true && d.IsSubstituteMatType == false select d).ToArray();
if (subMatSize.Any())
{
var mss = (from d in pmss where d.MatSizeID == subMatSize.First().DeafultMatSizeID select d).ToArray();
if(mss.Any())
{
MatProfileCall.MatSizeText = mss.First().MatSizeText;
MatProfileCall.MatSizeID = mss.First().MatSizeID;
MatProfileCall.MatTypeID = mss.First().MatTypeID;
return Result.Ok<EDIMaterialProFile>(MatProfileCall);
}
else
{ return Result.Fail<EDIMaterialProFile>(THC_Constants.sMICEDICONVERTERROR + "IsMapToMatSizeID is True but MatSizeID not found in MaterialSize"); }
}