この MFC コードのパフォーマンスを向上するにはどうすればよいですか?
-
12-10-2019 - |
質問
ファイル検索を実行すると、ディレクトリの例外リストが存在します。問題は、以下のコードがハードドライブ上のすべてのファイルを再帰的に反復していることです。動作しますが、遅いです。したがって、パフォーマンスを最適化するために支援が必要です。前もって感謝します。
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)
複雑。この場合は、aの使用を検討してください CMap
代わりにそれがあなたに与えるように O(log N)
検索(セットはマップよりもさらに適切ですが、MFCにはこれを持っていませんが、標準のライブラリを使用することもできます。 std::set
代わりは)。
どれくらい遅い?プロフィールしましたか?ハードディスク上でファイルを再帰的に検索している場合、それはあなたがI/Oバインドされている可能性が非常に高いので、より高速なストレージハードウェア(Solid Stateなど)を取得する以外に何もできません。
ファイルの一般的な検索を行っています。世の中にはこれをうまく行う製品が 100 万種類あり、それらはすべて最適化としてインデックス作成を使用しています。ここでの弱点はコードではなく、確かにディスクです。1,000,000 個の文字列の比較には、ディスク上の 1,000,000 個のファイルを列挙するのにかかる時間と比べれば、まったく時間がかかりません。
ここには、パフォーマンスに関する2つの基本的な問題があります。ハードドライブアクセスとディレクトリトラバーサルです。両方のあなた 五月 最適化できるようにします。
ハードドライブの最適化
休息のハードドライブは休む傾向があります。回転するシリンダーは、回転を続けるのが好きです。このように、ハードドライブにアクセスするボトルネックは、それを起動し、時間を探して、読み取り時間を読みます。アクセスの量を減らし、読み取りごとのデータの量を増やすと、パフォーマンスが向上します。
メモリアクセスは、ハードドライブアクセスよりも高速です。そのため、大量のデータをメモリに持ち、メモリを検索します。
ディレクトリ検索の最適化。
もしそうなら、「ページ」の木を想像してください。ツリー内の各ノードは、ゼロ以上のディレクトリまたはファイルのディレクトリです。残念ながら、ほとんどのOSでは、このデータ構造は効率的な検索に最適化されていません。
理想的な状況は、関連するすべてのディレクトリをメモリに持ち、それらを検索することです(メモリ内)。ファイルの場所がわかったら、ファイルへのランダムアクセスが比較的迅速になります。問題は、関連するディレクトリのみを読むことで検索時間を短縮することです。 IEは、無関係なディレクトリの読み取りの数を減らします。
ハードドライブでファイル検索を実行するほとんどのアプリケーションは、ドライブを読み取り、独自の最適化されたデータ構造を作成します。これは、エニショナウスの量のファイルやファイル検索が少ないケースを使用した巨大なハードドライブには最適ではない場合があります。
可能であれば、OSにできるだけ多くのディレクトリをメモリに保持するように指示してください。
パフォーマンスの向上:他のアプリケーションの削減。
一部のアプリケーションでは、知覚されるパフォーマンス時間は、同時に実行されている他のアプリケーションに依存します。コンパイラとインターネット検索を同時に実行すると、他のほとんどのアプリケーションが遅くなります。したがって、あなたと同時に実行することで必要ない他のアプリケーションを排除してみてください。また、アプリケーションの優先順位をレーシングする投資。
+1プロフィールの場合、最初に確かに。また、これは、 タスクパラレルライブラリ - 各ディレクトリが表示されているときにタスクを起動し、CPUでこれらすべてのコアを使用します -