Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aeveltstra/a11505d085d2ec93e3a0b6f0b6ec969e to your computer and use it in GitHub Desktop.
Save aeveltstra/a11505d085d2ec93e3a0b6f0b6ec969e to your computer and use it in GitHub Desktop.
Powershell: Measure folder traversal methods
param(
[Parameter(Mandatory=$true)][string]$Filter,
[Parameter(Mandatory=$true)][string]$Path
)
$current_year = (get-date).year;
$logging_time_format = "yyyyMMdd\tHHmmss";
$logging_time = Get-Date -Format $logging_time_format;
write-output "${logging_time}: Checking $Path for files that match filter ${Filter}.";
if (!(test-path $Path)) {
$logging_time = Get-Date -Format $logging_time_format;
write-output "${logging_time}: Aborting. No such folder: $Path.";
exit -1;
}
echo "Starting test A";
$subjects_A = @();
$measure_A = Measure-Command -Expression {
[reflection.assembly]::loadwithpartialname("Microsoft.VisualBasic") | Out-Null
$xs = @();
$date = (get-date).AddDays(-7);
try {
$xs = [Microsoft.VisualBasic.FileIO.FileSystem]::GetFiles(
$Path,
[Microsoft.VisualBasic.FileIO.SearchOption]::SearchTopLevelOnly,
$Filter
);
} catch { $_ }
$subjects_A = $xs | where {$_.LastWriteTime -le $date} `
| select -last 500 ;
}
echo "Done with test A. Results in ms: ";
$measure_A.TotalMilliseconds;
echo "Starting test B.";
$subjects_B = @();
$measure_B = Measure-Command -Expression {
$date = (get-date).AddDays(-7);
$subjects_B = [System.IO.Directory]::EnumerateFiles(
$Path,
$Filter,
"TopDirectoryOnly"
) | where {[System.IO.File]::GetLastWriteTime($_) -le $date} `
| select -last 500;
}
echo "Done with test B. Results in ms: ";
$measure_B.TotalMilliseconds;
echo "Starting test C.";
$subjects_C = @();
$measure_C = Measure-Command -Expression {
$date = (get-date).AddDays(-7);
$subjects_C = cmd.exe /c dir /B /O:D $Path\$Filter `
| select -first 500 `
| % { Join-Path -Path $Path -ChildPath $_} `
| % { [System.IO.FileInfo]($_) } `
| where {$_.LastWriteTime -le $date} | % { $_.FullName };
}
echo "Done with test C. Results in ms: ";
$measure_C.TotalMilliseconds;
echo "Starting test D.";
$subjects_D = @();
$measure_D = Measure-Command -Expression {
$date = (get-date).AddDays(-7);
$subjects_D = cmd.exe /c dir /B /O:D $Path\$Filter `
| select -first 500 `
| % { Join-Path -Path $Path -ChildPath $_} `
| where { [System.IO.File]::GetLastWriteTime($_) -le $date};
}
echo "Done with test D. Results in ms: ";
$measure_D.TotalMilliseconds;
echo "Starting test E.";
$subjects_E = @();
$measure_E = Measure-Command -Expression {
$date = (get-date).AddDays(-7);
$subjects_E = cmd.exe /c dir /B /O:D $Path\$Filter `
| % { Join-Path -Path $Path -ChildPath $_} `
| %{ [pscustomobject]@{
"date" = [System.IO.File]::GetLastWriteTime($_)
"file" = "$($Path)\$_"
}
} `
| where { $_.date -lt $date } `
| select -last 500 `
| % { $_.file };
}
echo "Done with test E. Results in ms: ";
$measure_E.TotalMilliseconds;
<#
echo "";
$len = $subjects_A.Count;
echo "Test A found $len files: ";
$subjects_A;
echo "";
$len = $subjects_B.Count;
echo "Test B found $len files: ";
$subjects_B;
echo "";
$len = $subjects_C.Count;
echo "Test C found $len files: ";
$subjects_C;
echo "";
$len = $subjects_D.Count;
echo "Test D found $len files: ";
$subjects_D;
echo "";
$len = $subjects_E.Count;
echo "Test E found $len files: ";
$subjects_E;
#>
@aeveltstra
Copy link
Author

Use this Powershell script to test which method of traversing folder contents works fastest in your Windows environment.

It runs 5 tests, each slightly different to a lot different.

Test A is the most different as it uses a Visual Basic file enumeration component. In all tests conducted thus far, test A is significantly faster (about 10x) than the others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment