将数据表中的每个字符串与列表中的字符串进行比较需要更长的时间。性能

时间:2013-11-14 15:02:21

标签: linq list optimization compare query-performance

我有一个200,000行的datatable,并希望使用list的行验证每一行并返回该字符串codesList .. 这需要很长时间。我想提高性能。

for (int i = 0; i < dataTable.Rows.Count; i++)
{
    bool isCodeValid = CheckIfValidCode(codevar, codesList,out CodesCount);
}

private bool CheckIfValidCode(string codevar, List<Codes> codesList, out int count)
{
    List<Codes> tempcodes=  codesList.Where(code => code.StdCode.Equals(codevar)).ToList();
    if (tempcodes.Count == 0)
    {
        RetVal = false;
        for (int i = 0; i < dataTable.Rows.Count; i++)
        {
            bool isCodeValid = CheckIfValidCode(codevar, codesList,out CodesCount);
        }
    }
}

private bool CheckIfValidCode(string codevar, List<Codes> codesList, out int count)
{
    List<Codes> tempcodes=  codesList.Where(code => code.StdCode.Equals(codevar)).ToList();
    if (tempcodes.Count == 0)
    {
        RetVal = false;
    }
    else
    {
        RetVal=true;
    }
    return bRetVal;
}

codelist是一个列表,其中还包含200000条记录。请建议。我使用了findAll,它占用了相同的时间,也使用了LINQ查询,这也需要相同的时间。

1 个答案:

答案 0 :(得分:0)

我想到了一些优化:

  • 您可以首先删除Tolist()
  • Count()替换为.Any(),如果结果中有项目,则返回true
  • 使用HashSet<Codes>替换List时可能会快得多(这需要您的Codes类正确实现HashCode和Equals。或者您可以使用{{HashSet<string>填充Codes.StdCode。 1}}
  • 看起来你根本就没有使用out count。删除它会使这种方法更快。计算计数需要您检查所有代码。
  • 您还可以将列表拆分为字典&gt;您可以通过获取代码的第一个字符来填充它。这会减少要大幅检查的代码数量,因为你可以用第一个字符排除95%的代码。
  • 告诉string.Equals使用StringComparison类型OrdinalOrdinalIgnoreCase来加快比较。

看起来您可以提前停止处理,.Any的使用在第二种方法中处理了这一点。可以在第一个中使用类似的构造,而不是使用for并循环遍历每一行,在发现第一个失败后可能会发生短路(除非此代码不完整并且您将每一行标记为无效)


类似的东西:

private bool CheckIfValidCode(string codevar, List<Codes> codesList)
{
    Hashset<string> codes = new Hashset(codesList.Select(c ==> code.StdCode));

    return codes.Contains(codevar);
    // or: return codes.Any(c => string.Equals(codevar, c, StringComparison.Ordinal);
}

如果你对计数坚持不懈:

private bool CheckIfValidCode(string codevar, List<Codes> codesList, out int count)
{
    Hashset<string> codes = new Hashset(codesList.Select(c ==> code.StdCode));

    count = codes.Count(codevar);
    // or: count = codes.Count(c => string.Equals(codevar, c, StringComparison.Ordinal);

    return count > 0;
}

您可以通过在调用之外创建HashSet并重新使用实例来进一步优化:

InCallingCode
{
   ...
   Hashset<string> codes = new Hashset(codesList.Select(c ==> code.StdCode));

   for (/*loop*/) {
       bool isValid = CheckIfValidCode(codevar, codes, out int count) 
   }
   ....
}


private bool CheckIfValidCode(string codevar, List<Codes> codesList, out int count)
{
    count = codes.Count(codevar);
    // or: count = codes.Count(c => string.Equals(codevar, c, StringComparison.Ordinal);

    return count > 0;
}