diff --git a/test/perf/benchmarks/README.md b/test/perf/benchmarks/README.md
index 0da4361630f..f8c513a2d9a 100644
--- a/test/perf/benchmarks/README.md
+++ b/test/perf/benchmarks/README.md
@@ -24,12 +24,12 @@ This folder contains micro benchmarks that test the performance of PowerShell En
You can run the benchmarks directly using `dotnet run` in this directory:
1. To run the benchmarks in Interactive Mode, where you will be asked which benchmark(s) to run:
```
- dotnet run -c release
+ dotnet run -c Release
```
2. To list all available benchmarks ([read more](https://github.com/dotnet/performance/blob/main/docs/benchmarkdotnet.md#Listing-the-Benchmarks)):
```
- dotnet run -c release --list [flat/tree]
+ dotnet run -c Release --list [flat/tree]
```
3. To filter the benchmarks using a glob pattern applied to `namespace.typeName.methodName` ([read more](https://github.com/dotnet/performance/blob/main/docs/benchmarkdotnet.md#Filtering-the-Benchmarks)]):
diff --git a/test/perf/benchmarks/powershell-perf.csproj b/test/perf/benchmarks/powershell-perf.csproj
index 860948202a6..78608c2e96f 100644
--- a/test/perf/benchmarks/powershell-perf.csproj
+++ b/test/perf/benchmarks/powershell-perf.csproj
@@ -12,16 +12,25 @@
$(NoWarn);CS8002
true
-
- $(PERF_TARGET_VERSION)
-
AnyCPU
portable
true
+
+
+ $(PERF_TARGET_VERSION)
+
+
+
+ netcoreapp3.1;net5.0;net6.0
+
+ 7.1.3
+ 7.0.6
@@ -40,7 +49,17 @@
+
+
+
+
+
+
+
+
diff --git a/test/perf/perf.psm1 b/test/perf/perf.psm1
index 6bea86ff899..a623a2290dd 100644
--- a/test/perf/perf.psm1
+++ b/test/perf/perf.psm1
@@ -14,9 +14,15 @@ function Start-Benchmarking
The version of 'Microsoft.PowerShell.SDK' package that we want the benchmark to target.
The supported versions are 7.0.x and above, including preview versions.
+ .PARAMETER TargetFramework
+ The target framework to run benchmarks against.
+
.PARAMETER List
List the available benchmarks, in either 'flat' or 'tree' views.
+ .PARAMETER Runtime
+ Run benchmarks against multiple .NET runtimes.
+
.PARAMETER Filter
One or more wildcard patterns to filter the benchmarks to be executed or to be listed.
@@ -26,16 +32,26 @@ function Start-Benchmarking
.PARAMETER KeepFiles
Indicates to keep all temporary files produced for running benchmarks.
#>
- [CmdletBinding()]
+ [CmdletBinding(DefaultParameterSetName = 'Default')]
param(
+ [Parameter(ParameterSetName = 'Default')]
[ValidatePattern(
'^7\.(0|1|2)\.\d+(-preview\.\d{1,2})?$',
ErrorMessage = 'The package version is invalid or not supported')]
[string] $TargetPSVersion,
+ [Parameter(ParameterSetName = 'Default')]
+ [ValidateSet('netcoreapp3.1', 'net5.0', 'net6.0')]
+ [string] $TargetFramework = 'net6.0',
+
+ [Parameter(ParameterSetName = 'Default')]
[ValidateSet('flat', 'tree')]
[string] $List,
+ [Parameter(Mandatory, ParameterSetName = 'Runtimes')]
+ [ValidateSet('netcoreapp3.1', 'net5.0', 'net6.0')]
+ [string[]] $Runtime,
+
[string[]] $Filter = '*',
[string] $Artifacts,
[switch] $KeepFiles
@@ -53,6 +69,34 @@ function Start-Benchmarking
if (Test-Path -Path $Artifacts) {
Remove-Item -Path $Artifacts -Recurse -Force -ErrorAction Stop
}
+
+ if ($TargetPSVersion) {
+ ## Validate the specified 'TargetPSVersion' and 'TargetFramework' are compatible.
+ $TargetFramework -match '\d.\d' > $null
+ $targetDotNetVersion = $Matches[0]
+
+ $minimalDotNetVersion = switch -Wildcard ($TargetPSVersion) {
+ '7.0.*' { '3.1' }
+ '7.1.*' { '5.0' }
+ '7.2.*' { '6.0' }
+ }
+
+ if ($targetDotNetVersion -lt $minimalDotNetVersion) {
+ $dotnetVer = $minimalDotNetVersion -eq '3.1' ? 'netcoreapp3.1' : "net$minimalDotNetVersion"
+ throw "The '$TargetPSVersion' version of 'Microsoft.PowerShell.SDK' requires '$dotnetVer' as the minimal target framework."
+ }
+ }
+
+ if ($Runtime) {
+ ## Remove duplicate values.
+ $hash = [ordered]@{}
+ foreach ($item in $Runtime) {
+ if (-not $hash.Contains($item)) {
+ $hash.Add($item, $null)
+ }
+ }
+ $Runtime = $hash.Keys
+ }
}
End {
@@ -60,18 +104,36 @@ function Start-Benchmarking
Push-Location -Path "$PSScriptRoot/benchmarks"
$savedOFS = $OFS; $OFS = $null
- if ($TargetPSVersion) {
- Write-Log -message "Run benchmarks targeting the 'Microsoft.PowerShell.SDK' version $TargetPSVersion..."
- $env:PERF_TARGET_VERSION = $TargetPSVersion
- } else {
- Write-Log -message "Run benchmarks targeting the current PowerShell code base..."
- }
+ ## Aggregate BDN arguments.
+ $runArgs = @('--filter')
+ foreach ($entry in $Filter) { $runArgs += $entry }
+ $runArgs += '--artifacts', $Artifacts
+ $runArgs += '--envVars', 'POWERSHELL_TELEMETRY_OPTOUT:1'
- $runArgs = @()
if ($List) { $runArgs += '--list', $List }
if ($KeepFiles) { $runArgs += "--keepFiles" }
- dotnet run -c release --filter $Filter --artifacts $Artifacts --envVars POWERSHELL_TELEMETRY_OPTOUT:1 $runArgs
+ if ($PSCmdlet.ParameterSetName -eq 'Default') {
+ if ($TargetPSVersion) {
+ Write-Log -message "Run benchmarks targeting '$TargetFramework' and the 'Microsoft.PowerShell.SDK' version '$TargetPSVersion' ..."
+ $env:PERF_TARGET_VERSION = $TargetPSVersion
+ }
+ elseif ($TargetFramework -eq 'net6.0') {
+ Write-Log -message "Run benchmarks targeting the current PowerShell code base ..."
+ }
+ else {
+ Write-Log -message "Run benchmarks targeting '$TargetFramework' and the corresponding latest version of 'Microsoft.PowerShell.SDK' ..."
+ }
+
+ ## Use 'Release' instead of 'release' (note the capital case) because BDN uses 'Release' when building the auto-generated
+ ## project, and MSBuild somehow recognizes 'release' and 'Release' as two different configurations and thus will rebuild
+ ## all dependencies unnecessarily.
+ dotnet run -c Release -f $TargetFramework $runArgs
+ }
+ else {
+ Write-Log -message "Run benchmarks targeting multiple .NET runtimes: $Runtime ..."
+ dotnet run -c Release -f net6.0 --runtimes $Runtime $runArgs
+ }
if (Test-Path $Artifacts) {
Write-Log -message "`nBenchmark artifacts can be found at $Artifacts"
@@ -142,7 +204,7 @@ function Compare-BenchmarkResult
if ($Noise) { $runArgs += "--noise $Noise" }
if ($Top -gt 0) { $runArgs += "--top $Top" }
- dotnet run -c release --base $BaseResultPath --diff $DiffResultPath --threshold $Threshold "$runArgs"
+ dotnet run -c Release --base $BaseResultPath --diff $DiffResultPath --threshold $Threshold "$runArgs"
}
finally {
$OFS = $savedOFS