残念ながら、パフォーマンスを向上させるために使用できる特効薬ではありません。いつものように、速度とメモリのトレードオフになります。また、パフォーマンスが不足する可能性のある 2 つの側面があります。データベース サイトと HDD ドライブの I/O 速度です。
したがって、速度を上げるために、最初のステップでデータベースクエリのパフォーマンスを改善して、検索用の名前を十分に高速に返すことができるようにします。したがって、クエリが高速であり、おそらく (MS SQL の場合) キーワードを使用していることを確認してくださいREAD SEQUENTIAL
。名前を大きなブロックとして。
反対側の hdd 側では、いずれかを呼び出すことができますがDirectory.GetFiles()
、この呼び出しは、すべてのファイルを反復処理するまでブロックされ、すべてのファイル名を含む大きな配列が返されます。これはメモリを消費するパスであり、最初の検索には時間がかかりますが、後でその配列のみを操作すると、すべての連続検索で速度が向上します。別のアプローチは、呼び出すことですDirectory.EnumerateFiles()
これは、すべての呼び出しでオンザフライでドライブを検索するため、最初の検索では速度が向上する可能性がありますが、次の検索ではメモリストレージが発生せず、メモリフットプリントが改善されますが、速度が低下します。検索可能なメモリ内の配列。一方、OS は、同じファイルを何度も繰り返し処理し、下位レベルでキャッシュが発生することを検出した場合、キャッシュも実行します。
したがって、hdd サイトのチェックではDirectory.GetFiles()
、返された配列がメモリを消費せず、これですべての検索を実行する場合に使用します (HashSet
ファイル名のみまたはフル パスがデータベースから取得するものに依存する場合は、パフォーマンスをさらに向上させるために、おそらくそれを に入れます)それ以外の場合はDirectory.EnumerateFiles()
、OS で行われるキャッシングに最善を尽くしてください。
アップデート
あなたの質問とコメントを読み直した後、私が理解している限り、あなたのような名前があり、1234567891_w.jpg
名前のどの部分がディレクトリ部分を表しているのかわかりません。したがって、この場合、明示的な検索を行う必要があります。これは、すべてのディレクトリの反復処理に時間がかかるためです。これは、最初のショットでこれを解決する方法についてのアイデアを提供するサンプルコードです。
string rootDir = @"D:\RootDir";
// Iterate over all files reported from the database
foreach (var filename in databaseResults)
{
var fullPath = Path.Combine(rootDir, filename);
// Check if the file exists within the root directory
if (File.Exists(Path.Combine(rootDir, filename)))
{
// Report that the file exists.
DoFileFound(fullPath);
// Fast exit to continue with next file.
continue;
}
var directoryFound = false;
// Use the filename as a directory
var directoryCandidate = Path.GetFileNameWithoutExtension(filename);
fullPath = Path.Combine(rootDir, directoryCandidate);
do
{
// Check if a directory with the given name exists
if (Directory.Exists(fullPath))
{
// Check if the filename within this directory exists
if (File.Exists(Path.Combine(fullPath, filename)))
{
// Report that the file exists.
DoFileFound(fullPath);
directoryFound = true;
}
// Fast exit, cause we looked into the directory.
break;
}
// Is it possible that a shorter directory name
// exists where this file exists??
// If yes, we have to continue the search ...
// (Alternative code to the above one)
////// Check if a directory with the given name exists
////if (Directory.Exists(fullPath))
////{
//// // Check if the filename within this directory exists
//// if (File.Exists(Path.Combine(fullPath, filename)))
//// {
//// // Report that the file exists.
//// DoFileFound(fullPath);
//// // Fast exit, cause we found the file.
//// directoryFound = true;
//// break;
//// }
////}
// Shorten the directory name for the next candidate
directoryCandidate = directoryCandidate.Substring(0, directoryCandidate.Length - 1);
} while (!directoryFound
&& !String.IsNullOrEmpty(directoryCandidate));
// We did our best but we found nothing.
if (!directoryFound)
DoFileNotAvailable(filename);
}
私が考えることができる唯一のさらなるパフォーマンスの改善は、見つかったディレクトリをに入れ、これHashSet
をDirectory.Exists()
使用して既存のディレクトリをチェックすることですが、OSがすでにディレクトリルックアップでキャッシュを作成しているため、何も得られない可能性があります。ローカルキャッシュとほぼ同じ速度になります。しかし、これらのことについては、具体的な問題を測定するだけです。