Benchmark.psm1

function Get-Memory {
    return (get-process -pid $PID).WorkingSet64
}


Function Reset-Environment {
    [void] ([system.gc]::collect())
    [void] ([System.GC]::GetTotalMemory($true))
    [void] ([System.GC]::WaitForPendingFinalizers())
    start-sleep -seconds 2
}

Function Perform-Scenarios {
    param (
        $Scenarios,
        $Iterations
    )
    
    foreach ($Scenario in $Scenarios) {
        
        $Result = Perform-Scenario -Scenario $Scenario -Iterations $iterations
        
        write-host ""
        write-host "Run $($Result.Name)"
        write-host "- Iterations: $($Result["Iterations"])"
        write-host "- Memory Usage: $($Result["Memory Usage"] / 1MB) MB"
        write-host "- Runtime: $($Result["Runtime"]) ms"
    }
}

Function Perform-Scenario {
    param (
        $Scenario,
        $Iterations
    )
    Reset-Environment
    
    Perform-Benchmark -Name $Scenario.Name -ScriptBlock $Scenario.ScriptBlock -Iterations $Iterations
    
    Reset-Environment
}

Function Perform-Benchmark {
    param (
        $Name,
        $ScriptBlock,
        $Iterations
    )
    
    $BeforeMemory = Get-Memory
    
    $Runtime = Measure-Command {
        Perform-Iterations -ScriptBlock $ScriptBlock -Iterations $Iterations
    }
    
    $AfterMemory = Get-Memory
    
    $Memory = $AfterMemory - $BeforeMemory
    
    return @{
        "Name" = $Name
        "Iterations" = $Iterations
        "Memory Usage" = $Memory
        "Runtime" = $Runtime.totalMilliseconds
    }
    
}

Function Perform-Iterations {
    param (
        [scriptblock] $ScriptBlock,
        [int32] $Iterations
    )
    
    foreach ($i in 1..$Iterations) {
        Perform-Iteration -ScriptBlock $ScriptBlock
    }
}

Function Perform-Iteration {
    param (
        [scriptblock] $ScriptBlock
    )
    
    [void] (& $ScriptBlock)
}