我有一个 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
使用类型Ordinal
或OrdinalIgnoreCase
的StringComparison
来加快比较速度。
看起来您也可以更早地停止处理,使用 .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;
}