【发布时间】:2013-05-30 00:22:04
【问题描述】:
我正在比较从二进制文件生成的两个数据列表。我很清楚为什么它运行缓慢,当有大量记录时,它会做不必要的冗余工作。
例如,如果 a1 = a1,则条件为真。既然 2a != 1a 那么为什么还要麻烦检查呢?我需要从再次检查中消除 1a。如果我不这样做,它将在检查第 400,000 条记录时检查第一条记录。我想过将第二个 for 循环设为 foreach,但在遍历嵌套循环时无法删除 1a
“for 循环”中的项目数量可能会有所不同。我认为使用 'i' 的单个 for 循环不会起作用,因为匹配可以在任何地方。我正在读取二进制文件
这是我当前的代码。程序已经运行了一个多小时,它还在继续。出于可读性原因,我删除了很多迭代代码。
for (int i = 0; i < origItemList.Count; i++)
{
int modFoundIndex = 0;
Boolean foundIt = false;
for (int g = 0; g < modItemList.Count; g++)
{
if ((origItemList[i].X == modItemList[g].X)
&& (origItemList[i].Y == modItemList[g].Y)
&& (origItemList[i].Z == modItemList[g].Z)
&& (origItemList[i].M == modItemList[g].M))
{
foundIt = true;
modFoundIndex = g;
break;
}
else
{
foundIt = false;
}
}
if (foundIt)
{
/*
* This is run assumming it finds an x,y,z,m
coordinate. It thenchecks the database file.
*
*/
//grab the rows where the coordinates match
DataRow origRow = origDbfFile.dataset.Tables[0].Rows[i];
DataRow modRow = modDbfFile.dataset.Tables[0].Rows[modFoundIndex];
//number matched indicates how many columns were matched
int numberMatched = 0;
//get the number of columns to match in order to detect all changes
int numOfColumnsToMatch = origDbfFile.datatable.Columns.Count;
List<String> mismatchedColumns = new List<String>();
//check each column name for a change
foreach (String columnName in columnNames)
{
//this grabs whatever value is in that field
String origRowValue = "" + origRow.Field<Object>(columnName);
String modRowValue = "" + modRow.Field<Object>(columnName);
//check if they are the same
if (origRowValue.Equals(modRowValue))
{
//if they aren the same, increase the number matched by one
numberMatched++;
//add the column to the list of columns that don't match
}
else
{
mismatchedColumns.Add(columnName);
}
}
/* In the event it matches 15/16 columns, show the change */
if (numberMatched != numOfColumnsToMatch)
{
//Grab the shapeFile in question
Item differentAttrShpFile = origItemList[i];
//start blue highlighting
result += "<div class='turnBlue'>";
//show where the change was made at
result += "Change Detected at<br/> point X: " +
differentAttrShpFile.X + ",<br/> point Y: " +
differentAttrShpFile.Y + ",<br/>";
result += "</div>"; //end turnblue div
foreach (String mismatchedColumn in mismatchedColumns)
{
//iterate changes here
}
}
}
}
【问题讨论】:
-
您要处理多少条记录?
-
moditemlist 是否明显小于外部列表?然后,您只能遍历较小的列表,从而减少大量工作。您也许还可以将 x、y、z、m 的组合变成一种键来进行集合样式查找,而不是在整个列表中进行线性搜索?
-
另外,您可以尝试使用 foreach 循环而不是每次通过索引器访问吗?
-
大家好,他们通常拥有大约相同数量的记录。它们的大小从 20 到 250,000 不等。理想情况下,大文件不应超过几分钟。
-
我会对每个列表进行排序 O(NLogN),然后是合并顺序循环 O(N)。我对哈希很敏感,但原则上它们可以让你整体降低到 O(N)。
标签: c# asp.net optimization for-loop