Skip to content

Instantly share code, notes, and snippets.

@tjgruber
Created May 23, 2024 21:54
Show Gist options
  • Save tjgruber/b582afe23f5f30363b8f0886a8717196 to your computer and use it in GitHub Desktop.
Save tjgruber/b582afe23f5f30363b8f0886a8717196 to your computer and use it in GitHub Desktop.
Comparing Filters and Advanced Functions
<#
Inspired by this post (https://www.linkedin.com/posts/adambertram_powershell-activity-7197241312096501762-nj87), I got curious and
wanted to test the efficiency of each filters and advanced functions.
I remembered reading about them in a book years ago, advanced functions providing a better approach.
Here I got curious and wanted to give it a test.
Results for 3 100x runs:
Results of 100 runs:
Average Filter Execution Time: 477.022425 ms
Average Function Execution Time: 479.314339 ms
Filter was faster 50 times
Function was faster 50 times
Results of 100 runs:
Average Filter Execution Time: 466.893779 ms
Average Function Execution Time: 470.367392 ms
Filter was faster 56 times
Function was faster 44 times
Results of 100 runs:
Average Filter Execution Time: 468.284501 ms
Average Function Execution Time: 466.441952 ms
Filter was faster 50 times
Function was faster 50 times
#>
Filter Where-RunningProcess {
param(
[int]$MinMemoryUsageMB
)
# Additional processing for each process
if ($_.WorkingSet64 -gt ($MinMemoryUsageMB * 1MB)) {
$cpuUsage = ($_.CPU / ((Get-Date) - $_.StartTime).TotalSeconds) * 100
$memoryUsage = $_.WorkingSet64 / 1MB
$startTime = $_.StartTime.ToString("yyyy-MM-dd HH:mm:ss")
$nameReversed = -join ($_.Name.ToCharArray() | ForEach-Object { $_ })[-1..-($_.Name.Length)]
# Additional calculations
$complexCalculation = [Math]::Sqrt(($_.Id * $cpuUsage) + ($memoryUsage * 1024))
# Array and hashtable manipulations
$processInfoArray = @()
$processInfoHashtable = @{}
1..100 | ForEach-Object {
$processInfoArray += $_
$processInfoHashtable[$_] = $_ * 2
}
# Simulate I/O operations
$tempFilePath = [System.IO.Path]::GetTempFileName()
"Process: $($_.Name)" | Out-File -FilePath $tempFilePath
"Memory Usage: $memoryUsage MB" | Out-File -FilePath $tempFilePath -Append
"CPU Usage: $cpuUsage %" | Out-File -FilePath $tempFilePath -Append
# Clean up temporary file
Remove-Item -Path $tempFilePath -Force
[PSCustomObject]@{
Name = $_.Name
NameReversed = $nameReversed
Id = $_.Id
CPUUsage = "{0:N2}%" -f $cpuUsage
MemoryUsage = "{0:N2} MB" -f $memoryUsage
StartTime = $startTime
ComplexCalc = $complexCalculation
ArrayLength = $processInfoArray.Length
HashtableCount = $processInfoHashtable.Count
}
}
}
function Get-RunningProcess {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline=$true)]
[System.Diagnostics.Process]$Process,
[int]$MinMemoryUsageMB
)
process {
# Additional processing for each process
if ($Process.WorkingSet64 -gt ($MinMemoryUsageMB * 1MB)) {
$cpuUsage = ($Process.CPU / ((Get-Date) - $Process.StartTime).TotalSeconds) * 100
$memoryUsage = $Process.WorkingSet64 / 1MB
$startTime = $Process.StartTime.ToString("yyyy-MM-dd HH:mm:ss")
$nameReversed = -join ($Process.Name.ToCharArray() | ForEach-Object { $_ })[-1..-($Process.Name.Length)]
# Additional calculations
$complexCalculation = [Math]::Sqrt(($Process.Id * $cpuUsage) + ($memoryUsage * 1024))
# Array and hashtable manipulations
$processInfoArray = @()
$processInfoHashtable = @{}
1..100 | ForEach-Object {
$processInfoArray += $_
$processInfoHashtable[$_] = $_ * 2
}
# Simulate I/O operations
$tempFilePath = [System.IO.Path]::GetTempFileName()
"Process: $($Process.Name)" | Out-File -FilePath $tempFilePath
"Memory Usage: $memoryUsage MB" | Out-File -FilePath $tempFilePath -Append
"CPU Usage: $cpuUsage %" | Out-File -FilePath $tempFilePath -Append
# Clean up temporary file
Remove-Item -Path $tempFilePath -Force
[PSCustomObject]@{
Name = $Process.Name
NameReversed = $nameReversed
Id = $Process.Id
CPUUsage = "{0:N2}%" -f $cpuUsage
MemoryUsage = "{0:N2} MB" -f $memoryUsage
StartTime = $startTime
ComplexCalc = $complexCalculation
ArrayLength = $processInfoArray.Length
HashtableCount = $processInfoHashtable.Count
}
}
}
}
# Define the number of runs
$numberOfRuns = 100
# Initialize arrays to store execution times
$filterTimes = @()
$functionTimes = @()
# Run the tests X number of times
for ($i = 1; $i -le $numberOfRuns; $i++) {
# Measure filter execution time
$filterExecutionTime = Measure-Command {
Get-Process | Where-RunningProcess -MinMemoryUsageMB 50
}
$filterTimes += $filterExecutionTime.TotalMilliseconds
# Measure function execution time
$functionExecutionTime = Measure-Command {
Get-Process | Get-RunningProcess -MinMemoryUsageMB 50
}
$functionTimes += $functionExecutionTime.TotalMilliseconds
}
# Calculate average times
$avgFilterTime = ($filterTimes | Measure-Object -Average).Average
$avgFunctionTime = ($functionTimes | Measure-Object -Average).Average
# Calculate the number of times each was faster
$filterFasterCount = 0
$functionFasterCount = 0
for ($i = 0; $i -lt $numberOfRuns; $i++) {
if ($filterTimes[$i] -lt $functionTimes[$i]) {
$filterFasterCount++
} elseif ($functionTimes[$i] -lt $filterTimes[$i]) {
$functionFasterCount++
}
}
# Output the results
Write-Output "Results of $numberOfRuns runs:"
Write-Output "Average Filter Execution Time: $avgFilterTime ms"
Write-Output "Average Function Execution Time: $avgFunctionTime ms"
Write-Output "Filter was faster $filterFasterCount times"
Write-Output "Function was faster $functionFasterCount times"
# Output detailed results for each run (optional)
for ($i = 0; $i -lt $numberOfRuns; $i++) {
Write-Output "Run $($i + 1): Filter Time = $($filterTimes[$i]) ms, Function Time = $($functionTimes[$i]) ms"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment