我进行文件搜索并且有目录的例外列表,问题是在代码下面递归遍历硬盘上的所有文件。它有效,但很慢。因此,我需要帮助来优化其性能。提前谢谢。
CFileFind finder;
// build a string with wildcards
CString strWildcard(directory);
strWildcard += _T("\\*.*");
// start working for files
BOOL bWorking = finder.FindFile(strWildcard);
while (bWorking)
{
bWorking = finder.FindNextFile();
if (finder.IsDots())
continue;
// if it's a directory, recursively search it
if (finder.IsDirectory())
{
CString str = finder.GetFilePath();
if(NULL == m_searchExceptions.Find(str)){
_recursiveSearch(str);
}
else{
continue;
}
}
//basic comparison, can be replaced by strategy pattern if complicated comparsion required (e.g. REGEX)
if(0 == finder.GetFileName().CompareNoCase(m_searchPattern)){
if(m_currentSearchResults.Find(finder.GetFilePath()) == NULL){
m_currentSearchResults.AddHead(finder.GetFilePath());
}
}
}
答案 0 :(得分:3)
看起来您的m_currentSearchResults
是一个列表,每次找到文件名时,如果它已经在列表中,您可以查找它。如果您有大量已找到的文件(比如数百个),这可能会成为瓶颈,因为它具有O(N^2)
复杂性。如果是这种情况,请考虑使用CMap
,因为它会为您提供O(log N)
搜索(一个集合比地图更合适,但您在MFC中没有这个,但您也可以使用标准库的std::set
代替。)
答案 1 :(得分:1)
有多慢?你有资料吗?如果您以递归方式搜索硬盘上的文件,那么极有可能是您受到I / O限制,并且除了获得更快的存储硬件(如固态)之外,没有什么可以做的。
答案 2 :(得分:0)
我认为你不能在这里优化性能。无论你在优化方面做了什么,你都会花费80%以上的时间在FindFirstFile
和FindNextFile
这里(Windows API调用)。
答案 3 :(得分:0)
您正在搜索文件。有一百万种产品做得很好,它们都使用索引作为优化。这里的弱链接肯定是你的磁盘,而不是你的代码。与在磁盘上枚举1,000,000个文件所花费的时间相比,比较1,000,000个字符串将花费时间。
答案 4 :(得分:0)
这里有两个关于性能的基本问题:硬盘访问和目录遍历。您可能都可以进行优化。
静止的硬盘往往会保持休息状态。旋转滚筒喜欢保持旋转。如上所述,硬盘访问的瓶颈正在启动,寻找时间和阅读时间。减少访问量并增加每次读取的数据量将提高您的性能。
内存访问速度比硬盘驱动器访问速度快。所以将大块数据传输到内存中,然后搜索内存。
想象一下,如果你愿意,可以选择一个“页面”树。树中的每个节点都是零个或多个目录或文件的目录。不幸的是,在大多数操作系统中,这种数据结构并未针对高效搜索进行优化。
理想的情况是将所有相关目录拖入内存然后搜索它们(在内存中)。一旦知道文件的位置,对文件的随机访问就相对较快。问题是只通过阅读相关目录来缩短搜索时间;即减少无关目录读取的数量。
在硬盘驱动器上执行文件搜索的大多数应用程序都会读取驱动器并创建自己的优化数据结构。对于具有大量文件或少量文件搜索的大型硬盘驱动器而言,这可能不是最佳选择。
如果可以,请告诉操作系统尽可能多地保留内存中的目录。
对于某些应用程序,感知的性能时间取决于同时运行的其他应用程序。同时运行编译器和Internet搜索将减慢大多数其他应用程序的速度。因此,尝试消除与您同时运行不必要的其他应用程序。此外,投资会优先考虑您的申请。
答案 5 :(得分:0)
+1首先确定配置文件。此外,这似乎也是一个问题,也可以使用Task Parallel Library解决 - 在您看到每个目录时启动任务,并在CPU上使用所有这些核心 -