Skip to content

Commit

Permalink
Add benchmark code
Browse files Browse the repository at this point in the history
  • Loading branch information
martinothamar committed May 25, 2024
1 parent 8025cf2 commit a2d11a4
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -377,3 +377,6 @@ src/Altinn.Apps/AppTemplates/AspNet/App/Properties/launchSettings.json
*.iml

.mono/

# Benchmark Results
BenchmarkDotNet.Artifacts/
9 changes: 9 additions & 0 deletions AppLibDotnet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.App.Analyzers", "src
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.App.Analyzers.Tests", "test\Altinn.App.Analyzers.Tests\Altinn.App.Analyzers.Tests.csproj", "{B7E436DE-AF76-4979-9837-4243BAD94281}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmark", "benchmark", "{59E82256-BF35-4CE2-A0C3-473A4366CE9E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Altinn.App.Benchmarks", "benchmark\Altinn.App.Benchmarks\Altinn.App.Benchmarks.csproj", "{1E50EC1F-C6E4-4C7D-AB97-11CAB5F77682}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -52,6 +56,10 @@ Global
{B7E436DE-AF76-4979-9837-4243BAD94281}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7E436DE-AF76-4979-9837-4243BAD94281}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7E436DE-AF76-4979-9837-4243BAD94281}.Release|Any CPU.Build.0 = Release|Any CPU
{1E50EC1F-C6E4-4C7D-AB97-11CAB5F77682}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E50EC1F-C6E4-4C7D-AB97-11CAB5F77682}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E50EC1F-C6E4-4C7D-AB97-11CAB5F77682}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E50EC1F-C6E4-4C7D-AB97-11CAB5F77682}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -63,6 +71,7 @@ Global
{1745B251-BD5C-43B7-BA7D-9C4BFAB37535} = {7AD5FADE-607F-4D5F-8511-6647D0C1AA1C}
{9F956488-F123-48A2-B21A-2C2918E8B416} = {7AD5FADE-607F-4D5F-8511-6647D0C1AA1C}
{B7E436DE-AF76-4979-9837-4243BAD94281} = {6C8EB054-1747-4BAC-A637-754F304BCAFA}
{1E50EC1F-C6E4-4C7D-AB97-11CAB5F77682} = {59E82256-BF35-4CE2-A0C3-473A4366CE9E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4584C6E1-D5B4-40B1-A8C4-CF4620EB0896}
Expand Down
32 changes: 32 additions & 0 deletions benchmark/Altinn.App.Benchmarks/Altinn.App.Benchmarks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<LangVersion>latest</LangVersion>
<TargetFramework>net8.0</TargetFramework>
<Nullable>disable</Nullable>
<DebugType>pdbonly</DebugType>
<DebugSymbols>true</DebugSymbols>
<GenerateDocumentationFile>false</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<Using Include="BenchmarkDotNet.Attributes" />
<Using Include="BenchmarkDotNet.Order" />
<Using Include="BenchmarkDotNet.Configs" />
<Using Include="BenchmarkDotNet.Jobs" />
<Using Include="BenchmarkDotNet.Diagnosers" />
<Using Include="BenchmarkDotNet.Loggers" />
<Using Include="BenchmarkDotNet.Columns" />
<Using Include="BenchmarkDotNet.Reports" />
<Using Include="BenchmarkDotNet.Diagnostics.dotTrace" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.12" />
<PackageReference Include="BenchmarkDotNet.Diagnostics.dotTrace" Version="0.13.12" />
<PackageReference Include="Buildalyzer.Workspaces" Version="7.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Altinn.App.Analyzers\Altinn.App.Analyzers.csproj" />
<ProjectReference Include="..\..\src\Altinn.App.Api\Altinn.App.Api.csproj" />
<ProjectReference Include="..\..\src\Altinn.App.Core\Altinn.App.Core.csproj" />
</ItemGroup>
</Project>
148 changes: 148 additions & 0 deletions benchmark/Altinn.App.Benchmarks/Analyzers/AnalyzerBenchmarks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Altinn.App.Analyzers;
using Buildalyzer;
using Buildalyzer.Workspaces;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;

namespace Altinn.App.Benchmarks.Analyzers;

[Config(typeof(Config))]
public class AnalyzerBenchmarks
{
private AdhocWorkspace _workspace;
private Project _project;
private CompilationWithAnalyzersOptions _options;
private ImmutableArray<DiagnosticAnalyzer> _analyzers;

[GlobalSetup]
public void Setup()
{
var dir = GetTestAppDirectory();

var manager = new AnalyzerManager();
var analyzer = manager.GetProject(Path.Combine(dir.FullName, "App", "App.csproj"));
var projectDir = Path.Combine(dir.FullName, "App");
_workspace = analyzer.GetWorkspace();
var solution = _workspace.CurrentSolution;
_project = solution.Projects.Single(p => p.Name == "App");

var globalOptions = new Dictionary<string, string>()
{
["build_property.projectdir"] = projectDir
}.ToImmutableDictionary();
_options = new CompilationWithAnalyzersOptions(
new AnalyzerOptions(
[],
new TestOptionsProvider(
ImmutableDictionary<object, AnalyzerConfigOptions>.Empty,
new TestAnalyzerConfigOptions(globalOptions)
)
),
static (ex, analyzer, diagnostic) =>
throw new Exception($"Analyzer exception due to {diagnostic.Id}: {ex}"),
concurrentAnalysis: true,
logAnalyzerExecutionTime: true
);
_analyzers = [new MetadataAnalyzer()];
}

[Benchmark]
public async Task<ImmutableArray<Diagnostic>> AnalyzeMetadata()
{
var compilation = await _project.GetCompilationAsync();
var compilationWithAnalyzers = compilation.WithAnalyzers(_analyzers, _options);

return await compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync();
}

private sealed class Config : ManualConfig
{
public Config()
{
this.SummaryStyle = SummaryStyle.Default.WithRatioStyle(RatioStyle.Trend);
this.AddDiagnoser(MemoryDiagnoser.Default);
this.AddDiagnoser(new DotTraceDiagnoser());
this.AddColumn(RankColumn.Arabic);
this.Orderer = new DefaultOrderer(SummaryOrderPolicy.SlowestToFastest, MethodOrderPolicy.Declared);
}
}

private static DirectoryInfo GetTestAppDirectory()
{
var currentDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var dir = new DirectoryInfo(currentDir);
var slnFile = "AppLibDotnet.sln";
for (int i = 0; i < 25 && dir is not null && dir.GetFiles(slnFile).Length == 0; i++)
dir = dir.Parent;
if (dir is null)
throw new InvalidOperationException("Could not find root directory for repo");

var testAppDir = Path.Combine(dir.FullName, "test", "Altinn.App.Analyzers.Tests", "testapp");
var result = new DirectoryInfo(testAppDir);
if (!dir.Exists)
throw new InvalidOperationException("Could not find testapp directory");
return result;
}

private sealed class TestOptionsProvider : AnalyzerConfigOptionsProvider
{
private readonly ImmutableDictionary<object, AnalyzerConfigOptions> _treeDict;

public static TestOptionsProvider Empty { get; } =
new TestOptionsProvider(
ImmutableDictionary<object, AnalyzerConfigOptions>.Empty,
TestAnalyzerConfigOptions.Empty
);

internal TestOptionsProvider(
ImmutableDictionary<object, AnalyzerConfigOptions> treeDict,
AnalyzerConfigOptions globalOptions
)
{
_treeDict = treeDict;
GlobalOptions = globalOptions;
}

public override AnalyzerConfigOptions GlobalOptions { get; }

public override AnalyzerConfigOptions GetOptions(SyntaxTree tree) =>
_treeDict.TryGetValue(tree, out var options) ? options : TestAnalyzerConfigOptions.Empty;

public override AnalyzerConfigOptions GetOptions(AdditionalText textFile) =>
_treeDict.TryGetValue(textFile, out var options) ? options : TestAnalyzerConfigOptions.Empty;

internal TestOptionsProvider WithAdditionalTreeOptions(
ImmutableDictionary<object, AnalyzerConfigOptions> treeDict
) => new TestOptionsProvider(_treeDict.AddRange(treeDict), GlobalOptions);

internal TestOptionsProvider WithGlobalOptions(AnalyzerConfigOptions globalOptions) =>
new TestOptionsProvider(_treeDict, globalOptions);
}

private sealed class TestAnalyzerConfigOptions : AnalyzerConfigOptions
{
internal static readonly ImmutableDictionary<string, string> EmptyDictionary = ImmutableDictionary.Create<
string,
string
>(KeyComparer);

public static TestAnalyzerConfigOptions Empty { get; } = new TestAnalyzerConfigOptions(EmptyDictionary);

internal readonly ImmutableDictionary<string, string> Options;

public TestAnalyzerConfigOptions(ImmutableDictionary<string, string> options) => Options = options;

public override bool TryGetValue(string key, [NotNullWhen(true)] out string value) =>
Options.TryGetValue(key, out value);

public override IEnumerable<string> Keys => Options.Keys;
}
}
3 changes: 3 additions & 0 deletions benchmark/Altinn.App.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using BenchmarkDotNet.Running;

BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);

0 comments on commit a2d11a4

Please sign in to comment.