Skip to content

Commit 37549e3

Browse files
daxian-dbwrkeithhill
authored andcommitted
Add the performance benchmark project for PowerShell performance testing (PowerShell#15242)
1 parent 410f31a commit 37549e3

43 files changed

Lines changed: 2154 additions & 13 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,6 @@ StyleCop.Cache
8989

9090
# Ignore SelfSignedCertificate autogenerated files
9191
test/tools/Modules/SelfSignedCertificate/
92+
93+
# BenchmarkDotNet artifacts
94+
test/perf/BenchmarkDotNet.Artifacts/

.spelling

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,3 +1310,6 @@ codesign
13101310
release-BuildJson
13111311
yml
13121312
centos-7
1313+
- test/perf/benchmarks/README.md
1314+
benchmarked
1315+
BenchmarkDotNet

.vsts-ci/linux.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ trigger:
1414
- /.vsts-ci/misc-analysis.yml
1515
- /.github/ISSUE_TEMPLATE/*
1616
- /.dependabot/config.yml
17+
- test/perf/*
1718
pr:
1819
branches:
1920
include:
@@ -30,6 +31,7 @@ pr:
3031
- .vsts-ci/windows.yml
3132
- .vsts-ci/windows/*
3233
- test/common/markdown/*
34+
- test/perf/*
3335
- tools/releaseBuild/*
3436
- tools/releaseBuild/azureDevOps/templates/*
3537

.vsts-ci/mac.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ trigger:
1515
- /.vsts-ci/misc-analysis.yml
1616
- /.github/ISSUE_TEMPLATE/*
1717
- /.dependabot/config.yml
18+
- test/perf/*
1819
pr:
1920
branches:
2021
include:
@@ -31,6 +32,7 @@ pr:
3132
- /.vsts-ci/windows.yml
3233
- /.vsts-ci/windows/*
3334
- test/common/markdown/*
35+
- test/perf/*
3436
- tools/packaging/*
3537
- tools/releaseBuild/*
3638
- tools/releaseBuild/azureDevOps/templates/*

.vsts-ci/misc-analysis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ jobs:
8585
condition: succeededOrFailed()
8686
8787
- bash: |
88-
mdspell '**/*.md' '!**/Pester/**/*.md' --ignore-numbers --ignore-acronyms --report --en-us;
88+
mdspell '**/*.md' '!**/Pester/**/*.md' '!**/dotnet-tools/**/*.md' --ignore-numbers --ignore-acronyms --report --en-us;
8989
displayName: Test Spelling in Markdown
9090
condition: succeededOrFailed()
9191
workingDirectory: '$(repoPath)'

.vsts-ci/windows.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ trigger:
1414
- /.vsts-ci/misc-analysis.yml
1515
- /.github/ISSUE_TEMPLATE/*
1616
- /.dependabot/config.yml
17+
- test/perf/*
1718
pr:
1819
branches:
1920
include:
@@ -28,6 +29,7 @@ pr:
2829
- .github/ISSUE_TEMPLATE/*
2930
- .vsts-ci/misc-analysis.yml
3031
- test/common/markdown/*
32+
- test/perf/*
3133
- tools/packaging/*
3234
- tools/releaseBuild/*
3335
- tools/releaseBuild/azureDevOps/templates/*

src/System.Management.Automation/AssemblyInfo.cs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,13 @@
66
using System.Runtime.CompilerServices;
77

88
[assembly: InternalsVisibleTo("powershell-tests,PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
9+
[assembly: InternalsVisibleTo("powershell-perf,PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
910

10-
[assembly: InternalsVisibleTo("Microsoft.Test.Management.Automation.GPowershell.Analyzers,PublicKey=00240000048000009400000006020000002400005253413100040000010001003f8c902c8fe7ac83af7401b14c1bd103973b26dfafb2b77eda478a2539b979b56ce47f36336741b4ec52bbc51fecd51ba23810cec47070f3e29a2261a2d1d08e4b2b4b457beaa91460055f78cc89f21cd028377af0cc5e6c04699b6856a1e49d5fad3ef16d3c3d6010f40df0a7d6cc2ee11744b5cfb42e0f19a52b8a29dc31b0")]
11-
12-
#if NOT_SIGNED
13-
// These attributes aren't every used, it's just a hack to get VS to not complain
14-
// about access when editing using the project files that don't actually build.
15-
[assembly: InternalsVisibleTo(@"Microsoft.PowerShell.Commands.Utility")]
16-
[assembly: InternalsVisibleTo(@"Microsoft.PowerShell.Commands.Management")]
17-
[assembly: InternalsVisibleTo(@"Microsoft.PowerShell.Security")]
18-
[assembly: InternalsVisibleTo(@"System.Management.Automation.Remoting")]
19-
[assembly: InternalsVisibleTo(@"Microsoft.PowerShell.ConsoleHost")]
20-
#else
2111
[assembly: InternalsVisibleTo(@"Microsoft.PowerShell.Commands.Utility" + @",PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
2212
[assembly: InternalsVisibleTo(@"Microsoft.PowerShell.Commands.Management" + @",PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
2313
[assembly: InternalsVisibleTo(@"Microsoft.PowerShell.Security" + @",PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
2414
[assembly: InternalsVisibleTo(@"System.Management.Automation.Remoting" + @",PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
2515
[assembly: InternalsVisibleTo(@"Microsoft.PowerShell.ConsoleHost" + @",PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
26-
#endif
2716

2817
namespace System.Management.Automation
2918
{

test/perf/benchmarks/Categories.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
namespace MicroBenchmarks
5+
{
6+
public static class Categories
7+
{
8+
/// <summary>
9+
/// Benchmarks belonging to this category are executed for CI jobs.
10+
/// </summary>
11+
public const string Components = "Components";
12+
13+
/// <summary>
14+
/// Benchmarks belonging to this category are executed for CI jobs.
15+
/// </summary>
16+
public const string Engine = "Engine";
17+
18+
/// <summary>
19+
/// Benchmarks belonging to this category are targeting internal APIs.
20+
/// </summary>
21+
public const string Internal = "Internal";
22+
23+
/// <summary>
24+
/// Benchmarks belonging to this category are targeting public APIs.
25+
/// </summary>
26+
public const string Public = "Public";
27+
}
28+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using System.Management.Automation.Language;
5+
using BenchmarkDotNet.Attributes;
6+
using MicroBenchmarks;
7+
8+
namespace Engine
9+
{
10+
[BenchmarkCategory(Categories.Engine, Categories.Public)]
11+
public class Parsing
12+
{
13+
[Benchmark]
14+
public Ast UsingStatement()
15+
{
16+
const string Script = @"
17+
using module moduleA
18+
using Assembly assemblyA
19+
using namespace System.IO";
20+
return Parser.ParseInput(Script, out _, out _);
21+
}
22+
}
23+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using System.Collections.Generic;
5+
using System.Collections.ObjectModel;
6+
using System.Management.Automation;
7+
using System.Management.Automation.Runspaces;
8+
using System.Runtime.InteropServices;
9+
using BenchmarkDotNet.Attributes;
10+
using MicroBenchmarks;
11+
12+
namespace Engine
13+
{
14+
[BenchmarkCategory(Categories.Engine, Categories.Public)]
15+
public class Scripting
16+
{
17+
private Runspace runspace;
18+
private ScriptBlock scriptBlock;
19+
20+
private void SetupRunspace()
21+
{
22+
// Unless you want to run commands from any built-in modules, using 'CreateDefault2' is enough.
23+
runspace = RunspaceFactory.CreateRunspace(InitialSessionState.CreateDefault2());
24+
runspace.Open();
25+
Runspace.DefaultRunspace = runspace;
26+
}
27+
28+
#region Invoke-Method
29+
30+
[ParamsSource(nameof(ValuesForScript))]
31+
public string InvokeMethodScript { get; set; }
32+
33+
public IEnumerable<string> ValuesForScript()
34+
{
35+
yield return @"'String'.GetType()";
36+
yield return @"[System.IO.Path]::HasExtension('')";
37+
38+
// Test on COM method invocation.
39+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
40+
{
41+
yield return @"$sh=New-Object -ComObject Shell.Application; $sh.Namespace('c:\')";
42+
yield return @"$fs=New-Object -ComObject scripting.filesystemobject; $fs.Drives";
43+
}
44+
}
45+
46+
[GlobalSetup(Target = nameof(InvokeMethod))]
47+
public void GlobalSetup()
48+
{
49+
SetupRunspace();
50+
scriptBlock = ScriptBlock.Create(InvokeMethodScript);
51+
52+
// Run it once to get the C# code jitted and the script compiled.
53+
// The first call to this takes relatively too long, which makes the BDN's heuristic incorrectly
54+
// believe that there is no need to run many ops in each interation. However, the subsequent runs
55+
// of this method is much faster than the first run, and this causes 'MinIterationTime' warnings
56+
// to our benchmarks and make the benchmark results not reliable.
57+
// Calling this method once in 'GlobalSetup' is a workaround.
58+
// See https://github.com/dotnet/BenchmarkDotNet/issues/837#issuecomment-828600157
59+
scriptBlock.Invoke();
60+
}
61+
62+
[Benchmark]
63+
public Collection<PSObject> InvokeMethod()
64+
{
65+
return scriptBlock.Invoke();
66+
}
67+
68+
#endregion
69+
70+
[GlobalCleanup]
71+
public void GlobalCleanup()
72+
{
73+
runspace.Dispose();
74+
Runspace.DefaultRunspace = null;
75+
}
76+
}
77+
}

0 commit comments

Comments
 (0)