This is a real performance problem.
public int FindPreviousFC(int framecode)开发者_开发技巧
{
if (SetTable == null)
throw new NullReferenceException("Not loaded Log_Roadb.");
int previousFrameCode = 0;
for (int i = 0; i < SetTable.Rows.Count; i++)
{
if (framecode == Convert.ToInt32(SetTable.Rows[i][0]))
{
previousFrameCode = Convert.ToInt32(SetTable.Rows[i - 1][0]);
break;
}
}
return previousFrameCode;
}
If the data in the SetTable is ordered on framecode
than you can use a binary search through the data structure to reduce the number of lookups.
If there are not patterns in the data that you can exploit optimizing performance may become tricky. This assumes that you can't export the data from SetTable
into a structure where lookups are faster.
If this Find method is being called frequently on the same set of data, then you may also want to consider creating an index structure (dictionary) to speed up subsequent lookups. This may mitigate the cost of iterating over the same data over and over.
Also, as an aside, don't throw a
NullReferenceException
when you check the SetTable
argument, throw ArgumentNullExeception
instead. Null reference exceptions are thrown by the CLR when a reference variable that is null is dereferenced ... it shouldn't be thrown by your code.You might get some improvement by exchanging the rows with the columns in the table. Getting elements sequentially from a line in the table is faster than getting every nth element. (It has something to do with cache misses)
Most of your time is going to be spent converting text to integers. Since you say this is a time problem it sounds like you're calling this a lot--is there anything you can do to store the data as integers instead of strings?
Use a Dictionary.
Key -- SetTable.Rows[i][0]
Value -- SetTable.Rows[i-1][0].
Then when you get a framecode, just look it up in the dictionary. If it's there, return the value.
You can gain a little more efficiency by using Convert.Int32 on both the key and value before storing the in the Dictionary, then no further conversions are necessary.
Assuming
(1) SetTable is a DataTable
(2) framecodeColumn is perhaps your column name
(3) framecodeColumn occurs at index 0 (first column)
try the following:
SetTable.Select("framecodeColumn < framecodeValuePassedToYourMethod","framecodeColumn DESC")[0].[0]
Basically, find a DataRowCollection using "Select()" method by passing a filter, sort the result in descending order, and the first row will be the row that you are looking for.
Of course, please protect this line with all needed checks (like for example see if there is indeed results that satisfy the filter condition using the "GetLength()" method and so on).
精彩评论