Skip to content

Commit

Permalink
Fix build performance regression (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
martinothamar authored Mar 1, 2023
1 parent 568fdc3 commit 30ceab4
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Mediator.SourceGenerator;
using Mediator.SourceGenerator;
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
Expand All @@ -12,6 +12,7 @@ namespace Mediator.Benchmarks.SourceGenerator;
[Orderer(SummaryOrderPolicy.FastestToSlowest, MethodOrderPolicy.Declared)]
[InProcess]
//[EventPipeProfiler(EventPipeProfile.CpuSampling)]
//[EtwProfiler]
//[DisassemblyDiagnoser]
//[InliningDiagnoser(logFailuresOnly: true, allowedNamespaces: new[] { "Mediator" })]
public class SourceGeneratorBenchmark
Expand All @@ -38,7 +39,7 @@ public void Setup()

var projectFile = Path.Combine(
currentDirectory,
"../../samples/ASPNET_CleanArchitecture/AspNetSample.Api/AspNetSample.Api.csproj"
"../../samples/ASPNET_Core_CleanArchitecture/AspNetCoreSample.Api/AspNetCoreSample.Api.csproj"
);
if (!File.Exists(projectFile))
throw new Exception("Project doesnt exist");
Expand Down
16 changes: 16 additions & 0 deletions benchmarks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,19 @@ AMD Ryzen 5 5600X, 1 CPU, 12 logical and 6 physical cores
| SendStructRequest_MediatR | Singleton | 594.018 ns | 7.8648 ns | 7.3568 ns | 119.92 | 3.18 | 5 | 0.0839 | 1,416 B |


### Source generation

``` ini

BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22621
AMD Ryzen 5 5600X, 1 CPU, 12 logical and 6 physical cores
.NET SDK=6.0.202
[Host] : .NET 6.0.14 (6.0.1423.7309), X64 RyuJIT

Job=InProcess Toolchain=InProcessEmitToolchain

```
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Allocated |
|-------- |---------:|---------:|---------:|----------:|--------:|----------:|
| Compile | 14.52 ms | 0.249 ms | 0.233 ms | 1406.2500 | 31.2500 | 23 MB |

Original file line number Diff line number Diff line change
Expand Up @@ -311,22 +311,44 @@ private void FindGlobalNamespaces(Queue<INamespaceOrTypeSymbol> queue)

queue.Enqueue(compilation.Assembly.GlobalNamespace);

var markerSymbol = UnitSymbol;
if (markerSymbol is null)
throw new Exception("Can't load marker symbol");

foreach (var reference in compilation.References)
{
if (compilation.GetAssemblyOrModuleSymbol(reference) is not IAssemblySymbol assemblySymbol)
continue;

if (!assemblySymbol.Modules.Any(IsMediatorLibReferencedByTheModule))
if (_symbolComparer.Equals(markerSymbol.ContainingAssembly, assemblySymbol))
continue;
if (assemblySymbol.Name.StartsWith("Mediator.SourceGenerator", StringComparison.Ordinal))
continue;

if (!assemblySymbol.Modules.Any(static m => IsMediatorLibReferencedByTheModule(m, 0)))
continue;

queue.Enqueue(assemblySymbol.GlobalNamespace);
}
}

private static bool IsMediatorLibReferencedByTheModule(IModuleSymbol module)
private static bool IsMediatorLibReferencedByTheModule(IModuleSymbol module, int depth)
{
return module.ReferencedAssemblies.Any(ra => ra.Name == Constants.MediatorLib)
|| module.ReferencedAssemblySymbols.Any(ra => ra.Modules.Any(IsMediatorLibReferencedByTheModule));
if (module.ReferencedAssemblies.Any(static ra => ra.Name == Constants.MediatorLib))
return true;

// Above we've checked for direct dependencies on the Mediator.Abstractions package,
// but projects can implement Mediator messages using only a transitive dependency
// as well.
// Even so, going too deep recursively will severely impact build performance
// so for now the depth is limited to 3.
// This should be solved properly by changing how codegen works..
if (depth > 3)
return false;

return module.ReferencedAssemblySymbols.Any(
ra => ra.Modules.Any(m => IsMediatorLibReferencedByTheModule(m, depth + 1))
);
}

private void PopulateMetadata(Queue<INamespaceOrTypeSymbol> queue)
Expand Down

0 comments on commit 30ceab4

Please sign in to comment.