perf: check filesize first to reduce HashData alloc

This commit is contained in:
Oliver Booth 2024-04-17 19:24:22 +01:00
parent c77cb1a266
commit 921c1b19c1
Signed by: oliverbooth
GPG Key ID: E60B570D1B7557B5
1 changed files with 34 additions and 3 deletions

View File

@ -8,6 +8,7 @@ namespace FindDuplicates;
internal sealed class ListCommand : AsyncCommand<ListSettings> internal sealed class ListCommand : AsyncCommand<ListSettings>
{ {
private readonly ConcurrentDictionary<long, ConcurrentBag<FileInfo>> _fileSizeMap = new();
private readonly ConcurrentDictionary<string, ConcurrentBag<FileInfo>> _fileHashMap = new(); private readonly ConcurrentDictionary<string, ConcurrentBag<FileInfo>> _fileHashMap = new();
public override async Task<int> ExecuteAsync(CommandContext context, ListSettings settings) public override async Task<int> ExecuteAsync(CommandContext context, ListSettings settings)
@ -95,9 +96,15 @@ internal sealed class ListCommand : AsyncCommand<ListSettings>
{ {
foreach (FileInfo file in currentDirectory.EnumerateFiles()) foreach (FileInfo file in currentDirectory.EnumerateFiles())
{ {
string relativeFilePath = Path.GetRelativePath(inputDirectory.FullName, file.FullName); try
AnsiConsole.MarkupLineInterpolated($"Checking hash for [cyan]{relativeFilePath}[/]"); {
tasks.Add(Task.Run(() => ProcessFile(file, settings))); ConcurrentBag<FileInfo> cache = _fileSizeMap.GetOrAdd(file.Length, _ => []);
cache.Add(file);
}
catch (Exception ex)
{
AnsiConsole.MarkupLineInterpolated($"[red]Error:[/] {ex.Message}");
}
} }
} }
catch (Exception ex) catch (Exception ex)
@ -105,6 +112,30 @@ internal sealed class ListCommand : AsyncCommand<ListSettings>
AnsiConsole.MarkupLineInterpolated($"[red]Error:[/] {ex.Message}"); AnsiConsole.MarkupLineInterpolated($"[red]Error:[/] {ex.Message}");
} }
} }
foreach ((_, ConcurrentBag<FileInfo> files) in _fileSizeMap)
{
if (files.Count < 1)
continue;
tasks.Add(Task.Run(() =>
{
foreach (FileInfo file in files)
{
try
{
AnsiConsole.MarkupLineInterpolated($"Checking hash for [cyan]{file.Name}[/]");
ProcessFile(file, settings);
}
catch (Exception ex)
{
AnsiConsole.MarkupLineInterpolated($"[red]Error:[/] {ex.Message}");
}
}
}));
}
_fileSizeMap.Clear();
} }
private void ProcessFile(FileInfo file, ListSettings settings) private void ProcessFile(FileInfo file, ListSettings settings)