0

我进行文件搜索并且有目录的例外列表,问题是下面的代码递归地遍历硬盘驱动器上的所有文件。它有效,但速度很慢。因此,我需要帮助来优化其性能。提前致谢。

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());       
            }
        }
    }
4

6 回答 6

3

看起来你m_currentSearchResults是一个列表,每次你找到一个文件名时,如果它已经在列表中,你就会查找它。如果您有很多找到的文件(比如数百个),这可能会成为一个瓶颈,因为它具有O(N^2)复杂性。如果是这种情况,请考虑使用 aCMap代替,因为它可以为您提供O(log N)搜索(一组甚至比地图更合适,但您在 MFC 中没有此功能,但您也可以使用标准库的std::set代替)。

于 2010-12-23T15:32:29.867 回答
1

有多慢?你有介绍吗?如果您在硬盘上递归搜索文件,那么您极有可能受到 I/O 限制,除了获得更快的存储硬件(如固态)之外,您无能为力。

于 2010-12-23T15:19:59.383 回答
0

我认为您无法在这里优化性能。无论您在优化方面做什么,您都将在内部FindFirstFile和此处(Windows API 调用)花费 80+% 的时间。FindNextFile

我已经问了一个类似的问题,但还没有得到答案。

于 2010-12-23T15:20:27.933 回答
0

您正在对文件进行一般搜索。有一百万种产品在这方面做得很好,它们都使用索引作为优化。这里的薄弱环节当然是你的磁盘,而不是你的代码。与枚举磁盘上的 1,000,000 个文件所需的时间相比,比较 1,000,000 个字符串根本不需要时间。

于 2010-12-23T15:20:38.827 回答
0

这里有两个关于性能的基本问题:硬盘访问和目录遍历。两者都可以进行优化。

硬盘优化

静止的硬盘趋向于静止。一个旋转的圆柱体喜欢不停地旋转。因此,硬盘访问的瓶颈在于启动、寻道时间和读取时间。减少访问量并增加每次读取的数据量将提高您的性能。

内存访问比硬盘访问快。因此,将大量数据拖入内存,然后搜索内存。

优化目录搜索。

如果你愿意,想象一下“页面”树。树中的每个节点都是零个或多个目录或文件的目录。不幸的是,在大多数操作系统中,这种数据结构并未针对有效搜索进行优化。

理想的情况是将所有相关目录拖入内存,然后搜索它们(在内存中)。一旦知道文件的位置,对文件的随机访问就会相对较快。问题是通过仅阅读相关目录来减少搜索时间;即减少不相关的目录读取次数。

大多数在硬盘驱动器上执行文件搜索的应用程序都会读取驱动器并创建自己的优化数据结构。对于具有大量文件或文件搜索很少的大型硬盘驱动器,这可能不是最佳选择。

如果可以,请告诉操作系统在内存中保留尽可能多的目录。

提高性能:减少其他应用程序。

对于某些应用程序,感知的性能时间取决于同时运行的其他应用程序。同时运行编译器和互联网搜索会减慢大多数其他应用程序的速度。因此,请尝试消除与您的同时运行的其他不必要的应用程序。此外,投资会提高您的应用程序的优先级。

于 2010-12-23T19:09:01.317 回答
0

+1 配置文件首先要确定。此外,这似乎是一个也可以使用任务并行库解决的问题- 在您看到每个目录时启动一个任务,并使用您 CPU 上的所有这些内核 -

于 2010-12-25T12:58:25.643 回答