Как я могу повысить производительность в этом коде MFC?

StackOverflow https://stackoverflow.com/questions/4519985

Вопрос

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

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());       
            }
        }
    }
Это было полезно?

Решение

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

Я уже задал аналогичный вопрос и еще не получил ответ.

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top