0

我有datatable200,000 行,想用列表的行验证每一行并返回该字符串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 查询。

4

1 回答 1

0

想到了一些优化:

  • 您可以从Tolist()完全删除
  • 替换Count()with .Any(),如果结果中有项目则返回 true
  • 当您将 List 替换为 a 时,它可能也会快得多HashSet<Codes>(这需要您的 Codes 类正确实现 HashCode 和 Equals。或者,您可以HashSet<string>使用以下内容填充 aCodes.StdCode
  • 看起来你根本没有使用out count。删除它会使这种方法更快。计算计数需要您检查所有代码。
  • 您还可以通过获取代码的第一个字符将列表拆分为您填充的 ​​Dictionary>。这将大大减少要检查的代码数量,因为您可以按第一个字符排除 95% 的代码。
  • 告诉string.Equals使用 a StringComparisonof 类型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;
}
于 2013-11-14T15:17:27.860 回答