Add the performance benchmark project for PowerShell performance testing#15242
Conversation
There was a problem hiding this comment.
I wonder - has MSFT PowerShell team already internal perf LAB?
What is Baseline we should use? PowerShell 6.0? 7.0? Latest LTS version? Latest version?
Has MSFT team a roadmap for adding perf tests? I believe we need a perf test set with good code coverage.
Will perf tests be mandatory in new PRs to avoid perf regressions?
There was a problem hiding this comment.
Will DependaBot automatically update the package versions in all csproj files added in the PR?
There was a problem hiding this comment.
Please add the csproj here: https://github.com/PowerShell/PowerShell/blob/master/.github/dependabot.yml
|
#Addressed. |
|
@iSazonov The
No, unfortunately :( We used to have perf and stressing tests before open source for Windows PowerShell, but not for the open-sourced PowerShell.
It's based on what tests you are looking at. For CI regression tests, the baseline would be the results from the run without the PR changes. For high level regression tests, the base line would be the results from a previous preview, or a previous stable release.
No, we are still figuring things out. I also reached out to @adamsitnik for guidelines on performance testing in general.
Ideally, we will enable the perf test for CI, so that we know what's getting better/worse with the changes. We can leverage what dotnet team has for this, but the first thing for us is to have a good suite of perf tests. |
It would be great to have support of automatically creating these baselines in the scripts.
It seems it is impossible without a lab since a perf history can not be without the lab. |
| CorrelationId = environment.GetEnvironmentVariable("HELIX_CORRELATION_ID"), | ||
| PerfRepoHash = environment.GetEnvironmentVariable("PERFLAB_PERFHASH"), | ||
| Name = environment.GetEnvironmentVariable("PERFLAB_RUNNAME"), | ||
| Queue = environment.GetEnvironmentVariable("PERFLAB_QUEUE"), |
There was a problem hiding this comment.
all these env vars are specific to current dotnet/performance repo setup & CI. Do you plan to use .NET Performance Team hardware lab? If not, I think that you should not be including anything from
the Reporting folder
There was a problem hiding this comment.
We don't have a hardware lab, so it's definitely a preferable option for us if it's possible for us to run our perf tests in the .NET performance team hardware lab 😄. Even if we cannot use the .NET team lab, maybe it's still preferable for us to keep the same format of the exported reports, so that we can leverage the tools from the .NET performance teams easily?
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <!-- We are using a single TFM for this project, the drawback is that we cannot run benchmarks | ||
| targeting other .NET runtime versions, such as net5.0 (PS7.1) and netcoreapp3.1 (PS7.0) --> |
There was a problem hiding this comment.
this is something that we should discuss at the meeting as I would be very happy to help you ensure that you can benchmark various .NET and PowerShell releases
| namespace BenchmarkDotNet.Extensions | ||
| { | ||
| // a simplified copy of internal BDN type: https://github.com/dotnet/BenchmarkDotNet/blob/0445917bf93059f17cb09e7d48cdb5e27a096c37/src/BenchmarkDotNet/Disassemblers/Exporters/GithubMarkdownDisassemblyExporter.cs#L35-L80 | ||
| internal static class DiffableDisassemblyExporter |
There was a problem hiding this comment.
this type is a set of hacks that we have temporarily added to the performance repo and never had the time to provide a proper solution. IMO you should not be copying it and we should just make these types public in BenchmarkDotNet if DisassemblyDiagnoser does not meet your needs.
There was a problem hiding this comment.
Oh, didn't know that. Yeah, I don't think we would need anything beyond what DisassemblyDiagnoser supports.
I found the DiffableDisassemblyExporter is used in PerfLabExporter, so it's related to lab result reporting. Again, we'd like to use the same format for reporting like in .NET performance, so that it would be easier for us to leverage other tools available in .NET performance repo. From that perspective, maybe we should keep this type? Let's talk more about this in our meeting.
| CommandLineOptions.ParseAndRemoveStringsParameter(argsList, "--category-exclusion-filter", out categoryExclusionFilterValue); | ||
| CommandLineOptions.ParseAndRemoveBooleanParameter(argsList, "--disasm-diff", out getDiffableDisasm); | ||
|
|
||
| CommandLineOptions.ValidatePartitionParameters(partitionCount, partitionIndex); |
There was a problem hiding this comment.
to be honest with you I don't think that you are going to need any of these custom arguments in the near future:
- we have added
--partition-countand--partition-indexafter our portfolio has reached three thousands of benchmarks and running all of them was taking 5 hours. The partitioning allows for distributing this work amongst many machines. - we have added
--exclusion-filterand--category-exclusion-filterafter WebAssembly (WASM) supports was added to .NET Runtime and it turned out that we could not run multithreaded benchmarks for WASM because it's single threaded by design. --disasm-diffthis is something that we have added just to simplify the process of exporting generated disassembly to our ReportingSystem. If you would also like to do that we should just add it to BenchmarkDotNet and remove the reflection hacks.
There was a problem hiding this comment.
That's good to know. As for the --disasm-diff flag, we'd like to generate the same reporting as .NET performance, so that sounds like something we may need.
and remove the reflection hacks.
where is the reflection hack?
There was a problem hiding this comment.
The --partition-count and --partition-index sound useful to keep, though we won't need it for the foreseeable future. I hope we can also grow the number of our perf tests to the point that we need to use those 2 flags 😄
The --exclusion-filter and --category-exclusion-filter are also useful to us. We are planning to have Interal and Public categories, for benchmarks targeting the internal APIs and public APIs respectively. For benchmarks that targets the internal APIs, they won't run with the existing 7.0.x and 7.1.x PowerShell SDK packages because it requires InternalVisible attribute to be declared in the PowerShell assemblies. So we may need those 2 flags when running our benchmarks targeting the 7.0.x and 7.1.x packages.
There was a problem hiding this comment.
|
@daxian-dbw @adityapatwardhan I've reopened the bug that you have hit today: dotnet/BenchmarkDotNet#837 |
iSazonov
left a comment
There was a problem hiding this comment.
It is great we can pickup a baseline by targeting published packages.
Another hot scenario we could think is targeting "before the PR" or master git branch vs current dev branch.
|
Currently there is one issue when running the benchmarks targeting the current code base (with Actually, when running benchmarks with the ‘ProjectReference’ setting, the very first |
|
@adityapatwardhan I think this PR is ready to be merged. Improvement can come in separate PRs. |
|
Will look at it today |
| [GlobalSetup(Target = nameof(InvokeMethod))] | ||
| public void GlobalSetup() | ||
| { | ||
| SetupRunspace(); |
There was a problem hiding this comment.
Should we make sure that the PowerShell / .NET telemetry is off.
There was a problem hiding this comment.
Good question. Maybe we should disable it and I will do that from the command line level.
|
@adityapatwardhan Files in |
|
@daxian-dbw - just noticed there are 4 CodeFactor issues not under dotnet-tools.. could you fix them please? |
|
Maybe we can ask @TravisEz13 or @SteveL-MSFT to add the Instructions here: https://support.codefactor.io/i15-ignoring-code-files |
|
🎉 Handy links: |

PR Summary
Add the performance benchmark project for PowerShell performance testing.
The structure of the
test\perfdirectory isThe
benchmarksfolder contains the benchmark project, and will contain all the benchmarks we are going to write in future for testing PowerShell performance. It's targeting the .NET runtimenet6.0, and is able to target different versions of PS sdk nuget packages. By default, it runs the tests targeting the current code base.The
toolsfolder contains projects that are copied from dotnet/performance,the performance testing repository for the .NET runtime and framework libraries.
such as the
RecommendedConfigwhich defines the set of recommended configurations for running the dotnet benckmarks (we use the same config).which may be useful to us when running our benchmarks in lab.
It's very useful to show the regression of new changes by comparing its benchmark results to the baseline results.
The files that are copied from dotnet/performance are kept as is, without adding the copyright header used in PowerShell repository.
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:or[ WIP ]to the beginning of the title (theWIPbot will keep its status check atPendingwhile the prefix is present) and remove the prefix when the PR is ready.