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)複雑になるため、これがボトルネックになる可能性があります。この場合は、CMap代わりに a を使用してO(log N)検索することを検討してください (セットはマップよりもさらに適切ですが、MFC にはこれがありませんが、std::set代わりに標準ライブラリを使用することもできます)。

于 2010-12-23T15:32:29.867 に答える
1

どれくらい遅いですか?プロファイルしましたか?ハードディスク上のファイルを繰り返し検索している場合は、I / Oバウンドである可能性が非常に高く、より高速なストレージハードウェア(ソリッドステートなど)を入手する以外にできることはありません。

于 2010-12-23T15:19:59.383 に答える
0

ここでパフォーマンスを最適化できるとは思いません。最適化の観点から何をするにしても、時間の80%以上を内部FindFirstFileとここ(Windows API呼び出し)に費やすことになります。FindNextFile

私はすでに同様の質問をしましたが、まだ答えが得られていません。

于 2010-12-23T15:20:27.933 に答える
0

ファイルの一般的な検索を行っています。これをうまく行う製品は100万あり、それらはすべて最適化としてインデックス作成を使用しています。ここでの弱点は確かにディスクであり、コードではありません。1,000,000個の文字列を比較することは、ディスク上の1,000,000個のファイルを列挙するのにかかる時間と比較してまったく時間がかかりません。

于 2010-12-23T15:20:38.827 に答える
0

ここでのパフォーマンスには、ハード ドライブ アクセスとディレクトリ トラバーサルという 2 つの基本的な問題があります。どちらも最適化できる 場合があります。

ハード ドライブの最適化

静止状態のハード ドライブは、静止状態のままになる傾向があります。回転するシリンダーは回転し続けるのが好きです。つまり、ハード ドライブ アクセスのボトルネックは、起動、シーク時間、読み取り時間です。アクセス数を減らし、読み取りあたりのデータ量を増やすと、パフォーマンスが向上します。

メモリ アクセスは、ハード ドライブ アクセスよりも高速です。そのため、大量のデータをメモリに移動してから、メモリを検索します。

ディレクトリ検索の最適化。

「ページ」のツリーを想像してみてください。ツリーの各ノードは、0 個以上のディレクトリまたはファイルのディレクトリです。残念ながら、ほとんどの OS では、このデータ構造は効率的な検索のために最適化されていません。

理想的な状況は、関連するすべてのディレクトリをメモリに取り込み、それらを (メモリ内で) 検索することです。ファイルの場所がわかれば、そのファイルへのランダム アクセスは比較的迅速に行われます。問題は、関連するディレクトリのみを読み取ることで検索時間を短縮することです。つまり、無関係なディレクトリ読み取りの数を減らします。

ハード ドライブでファイル検索を実行するほとんどのアプリケーションは、ドライブを読み取り、独自の最適化されたデータ構造を作成します。これは、膨大な量のファイルがある巨大なハード ドライブや、ファイル検索がほとんど行われない場合には最適ではない可能性があります。

可能であれば、できるだけ多くのディレクトリをメモリに保持するように OS に指示します。

パフォーマンスの向上: 他のアプリケーションの削減。

一部のアプリケーションでは、認識されるパフォーマンス時間は、同時に実行されている他のアプリケーションによって異なります。コンパイラとインターネット検索を同時に実行すると、他のほとんどのアプリケーションの速度が低下します。そのため、同時に実行する必要のない他のアプリケーションを排除してみてください。また、アプリケーションの優先度を上げるために投資します。

于 2010-12-23T19:09:01.317 に答える
0

プロファイルの+1は、最初に確認してください。また、これはTask Parallel Libraryを使用して解決できる問題のようにも思えます - 各ディレクトリが表示されているときにタスクを起動し、CPU でそれらすべてのコアを使用します -

于 2010-12-25T12:58:25.643 に答える