C# 如何加快这些代码的速度,这是用来从两个网格中查找匹配记录的,两个网格的both有190000+;记录
假设我有两个网格,每个网格包含190000多条记录,分别命名为网格A和网格B 对于网格A中的每个记录,我想找出网格B中是否有相同的记录 网格A和网格B有相同的列,在我的例子中,它们的列是 col1 col2 col3 col4 它们的数据类型可能是 字符串数据时间双精度 到目前为止,我所做的是: 对于网格A中的每一行,循环遍历网格B中的所有行,并比较四个列 一个接一个 代码如下所示:C# 如何加快这些代码的速度,这是用来从两个网格中查找匹配记录的,两个网格的both有190000+;记录,c#,C#,假设我有两个网格,每个网格包含190000多条记录,分别命名为网格A和网格B 对于网格A中的每个记录,我想找出网格B中是否有相同的记录 网格A和网格B有相同的列,在我的例子中,它们的列是 col1 col2 col3 col4 它们的数据类型可能是 字符串数据时间双精度 到目前为止,我所做的是: 对于网格A中的每一行,循环遍历网格B中的所有行,并比较四个列 一个接一个 代码如下所示: //loop grid_A foreach (UltraGridRow row
//loop grid_A
foreach (UltraGridRow row in ultraGrid1.Rows)
{
List<object> lo = new List<object>();
for (int i=0;i<4;i++) //add col's value to ListA
{
lo.Add(row.Cells[i].Value);
}
//loop grid_B
foreach (UltraGridRow rowDist in ultraGrid2.Rows)
{
List<object> loDist = new List<object>();
for (int ii=0;ii<4;ii++) //add col's value to ListB
{
loDist.Add(rowDist.Cells[ii].Value);
}
if (CompareList(lo, loDist) == true) //compare two List
{
break;
}
}
}
// the function compare two List
private bool CompareList(List<object> a, List<object> b)
{
//Assert a.count==b.count
for (int i=0;i<a.Count;i++)
{
if (!CompareObject(a[i], b[i]))
return false;
}
return true;
}
//
private bool CompareObject(object oa, object ob)
{
// object is string
if (oa.GetType() == typeof(System.String))
{
try
{
string strOb = Convert.ToString(ob);
if (oa.ToString() == strOb)
return true;
else
return false;
}
catch
{
return false;
}
}
// object is datetime
if (oa.GetType() == typeof(System.DateTime))
{
try
{
DateTime dtOb = Convert.ToDateTime(ob);
if ((DateTime)oa == dtOb)
return true;
else
return false;
}
catch
{
return false;
}
}
//object is double
if (oa.GetType() == typeof(System.Double))
{
try
{
double ddOb = Convert.ToDouble(ob);
if ((double)oa == ddOb)
return true;
else
return false;
}
catch
{
return false;
}
}
return true;
}
//循环网格\u A
foreach(ultraGrid1.Rows中的UltraGridRow行)
{
List lo=新列表();
对于(int i=0;i如果您可以事先对两个网格进行排序,则可以大大减少比较次数。您可以为每个网格维护一个当前行索引(row_a
用于grid_a
,row_B
用于grid_B
),并遍历网格。对于每个比较(伪代码):
if(网格A[行A]<网格B[行B])
行A++;
if(网格A[行A]==网格B[行B])
{
//匹配记录
行A++;
行_B++;
}
if(网格A[行A]>网格B[行B])
行_B++;
如果您无法对网格进行排序,那么我不知道有什么方法可以避免您当前的算法。您只需尽可能优化单个行的比较。处理原始数据,而不是通过datagrid,这样您就不会有ultraGrid的开销,并且会加快速度
另一个想法是从每一行中创建一个字符串,并比较这两个字符串。例如,如果行为1,“text”,true,1/1/2001,则必须创建并排序包含字符串“1-text-true-1/1/2001”的列表,这样您的索引速度会快得多。因此,您想知道网格中是否有sa的记录我是网格中的一员。你可以改变你的算法,而不是嵌套的foreach
(导致O(n^2)复杂度,这是巨大的)
如果您首先遍历网格B
并计算每行的哈希值(例如,通过将数据组合成字符串形式,然后获取哈希值,但可能有更好的方法生成哈希值)。若您将这些散列作为键放入字典中,则值可以是对网格B
中的行的引用,也可以是所需的其他值。
然后您可以迭代网格A
,计算行的哈希值,并在字典中检查键是否存在。如果键存在,则在网格B
中有相同的行(例如,存储在字典中的值可能会引导您找到该行)。如果键不存在,则没有具有相同值的行
这种方法将使您的复杂性达到O(2n),通常简化为O(n)-我们将始终对数据进行两次迭代。这是一个显著的改进,但代价是更高的内存消耗。
这种方法是否更快可能取决于网格中记录的数量,但如果您有190k条记录,那么速度应该更快(尽管我现在无法测试,我将在晚上尝试这样做)。您的数据多久更改一次?是否ii
是错误或键入错误,请注意,您以后只需使用I
?(int ii=0;iit是一个键入错误,我已对其进行了修改。您的数据来自何处,如果基于SQL,则最好只在两个相似的数据源之间运行查询。我的数据是从Excel导入的。谢谢您的建议,我尝试添加一个字典,该字典的键是combine data的哈希代码,值是grid_B的行索引问题是,不同的组合数据可能会生成相同的哈希代码,但这可以通过附加检查来解决。因此,您的解决方案仍然非常有价值,它对我帮助很大,谢谢。如果组合数据不完全相同,则哈希冲突的机会非常低。这就是散列-即使是非常相似的数据(如1个字符不同)也会生成非常不同的散列值)。仍然-可能会发生冲突,额外的检查可能有用,但很少
if (grid_A[row_A] < grid_B[row_B])
row_A++;
if (grid_A[row_A] == grid_B[row_B])
{
// matching record
row_A++;
row_B++;
}
if (grid_A[row_A] > grid_B[row_B])
row_B++;