gpt4 book ai didi

c# - 我有一个性能不佳的方法,我该如何提高它的效率?

转载 作者:太空狗 更新时间:2023-10-29 22:08:41 25 4
gpt4 key购买 nike

我有一个简单的方法来将 FileInfo 对象数组与文件名列表进行比较,以检查哪些文件已经被处理过。然后返回未处理的列表。

此方法的循环迭代了大约 250,000 个 FileInfo 对象。这花费了大量的时间来竞争。

效率低下显然是对 processedFiles 集合的 Contains 方法调用。

首先,我如何检查以确保我对原因的怀疑是真实的,其次,我如何改进方法以加快该过程?

public static List<FileInfo> GetUnprocessedFiles(FileInfo[] allFiles, List<string> processedFiles)
{
List<FileInfo> unprocessedFiles = new List<FileInfo>();
foreach (FileInfo fileInfo in allFiles)
{
if (!processedFiles.Contains(fileInfo.Name))
{
unprocessedFiles.Add(fileInfo);
}
}
return unprocessedFiles;
}

最佳答案

A List<T>Contains方法以线性时间运行,因为它可能必须枚举整个列表以证明项目的存在/不存在。我建议你使用 HashSet<string>或类似的代替。 HashSet<T> Contains方法旨在以常量 O(1) 运行时间,即它不应该取决于集合中的项目数量。

这个小改动应该可以使整个方法在线性时间内运行:

public static List<FileInfo> GetUnprocessedFiles(FileInfo[] allFiles, 
List<string> processedFiles)
{
List<FileInfo> unprocessedFiles = new List<FileInfo>();
HashSet<string> processedFileSet = new HashSet<string>(processedFiles);

foreach (FileInfo fileInfo in allFiles)
{
if (!processedFileSet.Contains(fileInfo.Name))
{
unprocessedFiles.Add(fileInfo);
}
}

return unprocessedFiles;
}

如果可能的话,我会建议 3 项改进:

  1. 为了额外效率,在源中将处理过的文件存储在一个集合中,这样这个方法需要一个ISet<T>作为参数。这样,您就不必每次都重建集合。
  2. 尽量不要以这种方式混合和匹配相同 实体(stringFileInfo)的不同表示。选择一个并使用它。
  3. 您可能还想考虑 HashSet<T>.ExceptWith方法而不是自己做循环。请记住,这会改变集合。

如果您可以使用 LINQ,并且可以负担得起在每次调用时建立一个集合,那么还有另一种方法:

public static IEnumerable<string> GetUnprocessedFiles
(IEnumerable<string> allFiles, IEnumerable<string> processedFiles)
{
// null-checks here
return allFiles.Except(processedFiles);
}

关于c# - 我有一个性能不佳的方法,我该如何提高它的效率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4096679/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com