Как я могу увеличить производительность на этом коде MFC? - PullRequest
0 голосов
/ 23 декабря 2010

Я выполняю поиск файлов и есть список исключений для каталогов, проблема в том, что код ниже рекурсивно перебирает все файлы на жестких дисках.Это работает, но это медленно.Поэтому мне нужна помощь для оптимизации его работы.Заранее спасибо.

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

Ответы [ 6 ]

3 голосов
/ 23 декабря 2010

Похоже, ваш m_currentSearchResults является списком, и каждый раз, когда вы находите имя файла, вы просматриваете его, если оно уже есть в списке. В случае, когда у вас есть много найденных файлов (скажем, сотни), это может стать узким местом, так как имеет сложность O(N^2). Если это так, рассмотрите возможность использования CMap вместо этого, поскольку это дает вам поиск O(log N) (набор будет даже более подходящим, чем карта, но у вас его нет в MFC, но вы также можете использовать стандартную библиотеку std::set вместо).

1 голос
/ 23 декабря 2010

Как медленно?Вы профилировали это?Если вы осуществляете рекурсивный поиск файлов на жестком диске, весьма вероятно, что вы связаны с вводом / выводом, и вы ничего не можете сделать, кроме как получить более быстрое оборудование для хранения (например, твердотельное).

0 голосов
/ 25 декабря 2010

+1 для профиля это сначала чтобы быть уверенным.Кроме того, это похоже на проблему, которую также можно решить с помощью Task Parallel Library - запустите задачу, когда вы видите каждый каталог, и используйте все эти ядра на вашем ЦП -

0 голосов
/ 23 декабря 2010

Здесь есть две фундаментальные проблемы производительности: доступ к жесткому диску и обратный путь в каталогах.И вы можете оптимизировать.

Оптимизация жесткого диска

Жесткий диск в состоянии покоя имеет тенденцию оставаться в покое.Вращающийся цилиндр любит вращаться.Таким образом, узкие места в доступе к жесткому диску запускают его, ищут время и время чтения.Уменьшение количества обращений и увеличение количества данных за чтение увеличит вашу производительность.

Доступ к памяти быстрее, чем доступ с жесткого диска.Так что перетаскивайте большие куски данных в память, затем ищите в памяти.

Оптимизация поиска в каталоге.

Представьте себе, если хотите, дерево «страниц».Каждый узел в дереве - это каталог из нуля или более каталогов или файлов.К сожалению, в большинстве ОС эта структура данных не оптимизирована для эффективного поиска.

Идеальная ситуация - перетаскивать все соответствующие каталоги в память, а затем искать их (в памяти).Как только местоположение файла известно, произвольный доступ к файлу относительно быстрый.Проблема заключается в сокращении времени поиска путем чтения только соответствующих каталогов;т.е. уменьшение количества ненужных операций чтения каталогов.

Большинство приложений, которые выполняют поиск файлов на жестком диске, читают диск и создают свои собственные оптимизированные структуры данных.Это может быть не оптимально для огромных жестких дисков с огромным количеством файлов или случаев небольшого поиска файлов.

Если вы можете, попросите ОС хранить в памяти как можно больше каталогов.

Повышение производительности: сокращение других приложений.

Для некоторых приложений воспринимаемое время производительности зависит от других приложений, работающих одновременно.Одновременный запуск компилятора и поиска в Интернете замедлит работу большинства других приложений.Поэтому постарайтесь исключить другие приложения, которые не нужны для одновременного запуска с вашими.Кроме того, вкладывая средства в повышение приоритетности вашей заявки.

0 голосов
/ 23 декабря 2010

Вы делаете общий поиск файла. Есть миллион продуктов, которые делают это хорошо, и все они используют индексацию как оптимизацию. Слабым звеном здесь, безусловно, является ваш диск, а не ваш код. Сравнение 1 000 000 строк совсем не займет времени по сравнению со временем, которое требуется для перечисления 1 000 000 файлов на диске.

0 голосов
/ 23 декабря 2010

Я не думаю, что вы сможете оптимизировать производительность здесь. Вы будете тратить 80 +% своего времени на FindFirstFile и FindNextFile здесь (вызовы Windows API), независимо от того, что вы делаете с точки зрения оптимизации.

Я уже задавал похожий вопрос и пока не получил ответа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...