C# 如何加快这些代码的速度,这是用来从两个网格中查找匹配记录的,两个网格的both有190000+;记录

C# 如何加快这些代码的速度,这是用来从两个网格中查找匹配记录的,两个网格的both有190000+;记录,c#,C#,假设我有两个网格,每个网格包含190000多条记录,分别命名为网格A和网格B 对于网格A中的每个记录,我想找出网格B中是否有相同的记录 网格A和网格B有相同的列,在我的例子中,它们的列是 col1 col2 col3 col4 它们的数据类型可能是 字符串数据时间双精度 到目前为止,我所做的是: 对于网格A中的每一行,循环遍历网格B中的所有行,并比较四个列 一个接一个 代码如下所示: //loop grid_A foreach (UltraGridRow row

假设我有两个网格,每个网格包含190000多条记录,分别命名为网格A和网格B

对于网格A中的每个记录,我想找出网格B中是否有相同的记录

网格A和网格B有相同的列,在我的例子中,它们的列是

col1 col2 col3 col4

它们的数据类型可能是

字符串数据时间双精度

到目前为止,我所做的是:

对于网格A中的每一行,循环遍历网格B中的所有行,并比较四个列

一个接一个

代码如下所示:

        //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++;