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



我有一个 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 查询。

我想到了一些优化:

  • 您可以从完全删除Tolist()开始
  • Count()替换为 .Any() ,如果结果中有项目,则返回 true
  • 当您将 List 替换为 HashSet<Codes> 时,它也可能快得多(这需要您的 Codes 类正确实现哈希代码和等于。或者,您可以使用 Codes.StdCode 的内容填充HashSet<string>
  • 看起来您根本没有使用out count。删除它会使这种方法更快。计算计数需要您检查所有代码。
  • 您还可以将列表拆分为字典>通过获取代码的第一个字符来填充该字典。这将大大减少要检查的代码数量,因为您可以按代码的第一个字符排除 95% 的代码。
  • 告诉string.Equals使用类型 OrdinalOrdinalIgnoreCaseStringComparison来加快比较速度。

看起来您也可以更早地停止处理,使用 .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;
}

相关内容

  • 没有找到相关文章

最新更新