diff --git a/Directory.Packages.props b/Directory.Packages.props
index 17a949b9c6..8c48047653 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -101,4 +101,4 @@
-
\ No newline at end of file
+
diff --git a/TUnit.Core.SourceGenerator.Roslyn47/TUnit.Core.SourceGenerator.Roslyn47.csproj b/TUnit.Core.SourceGenerator.Roslyn47/TUnit.Core.SourceGenerator.Roslyn47.csproj
index 5474b65ce3..7a9abf09c6 100644
--- a/TUnit.Core.SourceGenerator.Roslyn47/TUnit.Core.SourceGenerator.Roslyn47.csproj
+++ b/TUnit.Core.SourceGenerator.Roslyn47/TUnit.Core.SourceGenerator.Roslyn47.csproj
@@ -6,4 +6,4 @@
-
\ No newline at end of file
+
diff --git a/TUnit.SourceGenerator.Benchmarks/Program.cs b/TUnit.SourceGenerator.Benchmarks/Program.cs
new file mode 100644
index 0000000000..4e4b4ab3cb
--- /dev/null
+++ b/TUnit.SourceGenerator.Benchmarks/Program.cs
@@ -0,0 +1,14 @@
+using BenchmarkDotNet.Running;
+using Microsoft.Build.Locator;
+using TUnit.SourceGenerator.Benchmarks;
+
+MSBuildLocator.RegisterDefaults();
+
+if (args is { Length: > 0 })
+{
+ BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
+}
+else
+{
+ BenchmarkRunner.Run();
+}
diff --git a/TUnit.SourceGenerator.Benchmarks/TUnit.SourceGenerator.Benchmarks.csproj b/TUnit.SourceGenerator.Benchmarks/TUnit.SourceGenerator.Benchmarks.csproj
new file mode 100644
index 0000000000..7309e3d09e
--- /dev/null
+++ b/TUnit.SourceGenerator.Benchmarks/TUnit.SourceGenerator.Benchmarks.csproj
@@ -0,0 +1,25 @@
+
+
+ Exe
+ net10.0
+ enable
+ enable
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TUnit.SourceGenerator.Benchmarks/TestMetadataGeneratorBenchmarks.cs b/TUnit.SourceGenerator.Benchmarks/TestMetadataGeneratorBenchmarks.cs
new file mode 100644
index 0000000000..7c1ce60261
--- /dev/null
+++ b/TUnit.SourceGenerator.Benchmarks/TestMetadataGeneratorBenchmarks.cs
@@ -0,0 +1,34 @@
+using BenchmarkDotNet.Attributes;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.MSBuild;
+using TUnit.Core.SourceGenerator.Generators;
+using TUnit.SourceGenerator.Benchmarks;
+
+namespace TUnit.SourceGenerator.Benchmarks;
+
+[MemoryDiagnoser]
+[InProcess]
+public class TestMetadataGeneratorBenchmarks
+{
+ private const string SampleProjectPath = "../TUnit.TestProject/TUnit.TestProject.csproj";
+
+ private MSBuildWorkspace? _workspace;
+ private GeneratorDriver? _sampleDriver;
+ private Compilation? _sampleCompilation;
+
+ [GlobalSetup(Target = nameof(Compile))]
+ public void SetupCompile() =>
+ (_sampleCompilation, _sampleDriver, _workspace) =
+ WorkspaceHelper.SetupAsync(SampleProjectPath)
+ .GetAwaiter()
+ .GetResult();
+
+ [Benchmark]
+ public GeneratorDriver Compile() => _sampleDriver!.RunGeneratorsAndUpdateCompilation(_sampleCompilation!, out _, out _);
+
+ [GlobalCleanup]
+ public void Cleanup()
+ {
+ _workspace?.Dispose();
+ }
+}
diff --git a/TUnit.SourceGenerator.Benchmarks/WorkspaceHelper.cs b/TUnit.SourceGenerator.Benchmarks/WorkspaceHelper.cs
new file mode 100644
index 0000000000..2a1cc7c6bb
--- /dev/null
+++ b/TUnit.SourceGenerator.Benchmarks/WorkspaceHelper.cs
@@ -0,0 +1,56 @@
+using System.Runtime.CompilerServices;
+using BenchmarkDotNet.Loggers;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.MSBuild;
+
+namespace TUnit.SourceGenerator.Benchmarks;
+
+public static class WorkspaceHelper
+{
+ private static string GetDirectoryRelativePath(string projectPath, [CallerFilePath] string callerFilePath = null!) =>
+ Path.Combine(Path.GetDirectoryName(callerFilePath)!, projectPath);
+
+ public static async Task<(Compilation, CSharpGeneratorDriver, MSBuildWorkspace)> SetupAsync( string projectPath)
+ where TSourceGenerator : IIncrementalGenerator, new()
+ {
+ MSBuildWorkspace workspace = MSBuildWorkspace.Create();
+ workspace.RegisterWorkspaceFailedHandler(args =>
+ {
+ ConsoleLogger.Default.WriteLineError("-------------------------");
+ ConsoleLogger.Default.WriteLineError(args.Diagnostic.ToString());
+ ConsoleLogger.Default.WriteLineError("-------------------------");
+ });
+
+ var projectFile = GetDirectoryRelativePath(projectPath);
+
+ if (!File.Exists(projectFile))
+ throw new Exception($"Project doesn't exist at {projectFile}");
+
+ ConsoleLogger.Default.WriteLine($"Project exists at {projectFile}");
+
+ Project project;
+ try
+ {
+ ConsoleLogger.Default.WriteLine("Loading project\n");
+ project = await workspace.OpenProjectAsync(projectFile);
+ ConsoleLogger.Default.WriteLine("\nLoaded project");
+ }
+ catch (Exception ex)
+ {
+ ConsoleLogger.Default.WriteError($"Error: {ex.Message}");
+ throw;
+ }
+
+ var compilation = await project.GetCompilationAsync();
+ if (compilation == null)
+ throw new InvalidOperationException("Compilation returned null");
+
+ var generator = new TSourceGenerator().AsSourceGenerator();
+
+ var driver =
+ CSharpGeneratorDriver.Create([generator], parseOptions: (CSharpParseOptions) project.ParseOptions!);
+
+ return (compilation, driver, workspace);
+ }
+}
diff --git a/TUnit.sln b/TUnit.sln
index 3350695215..7273f2676d 100644
--- a/TUnit.sln
+++ b/TUnit.sln
@@ -155,6 +155,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TUnit.FsCheck", "TUnit.FsCh
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TUnit.Example.FsCheck.TestProject", "TUnit.Example.FsCheck.TestProject\TUnit.Example.FsCheck.TestProject.csproj", "{3428D7AD-B362-4647-B1B0-72674CF3BC7C}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TUnit.SourceGenerator.Benchmarks", "TUnit.SourceGenerator.Benchmarks\TUnit.SourceGenerator.Benchmarks.csproj", "{F686AD4B-FC90-48B9-84C9-C7B16C2E13E5}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -897,6 +899,18 @@ Global
{3428D7AD-B362-4647-B1B0-72674CF3BC7C}.Release|x64.Build.0 = Release|Any CPU
{3428D7AD-B362-4647-B1B0-72674CF3BC7C}.Release|x86.ActiveCfg = Release|Any CPU
{3428D7AD-B362-4647-B1B0-72674CF3BC7C}.Release|x86.Build.0 = Release|Any CPU
+ {F686AD4B-FC90-48B9-84C9-C7B16C2E13E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F686AD4B-FC90-48B9-84C9-C7B16C2E13E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F686AD4B-FC90-48B9-84C9-C7B16C2E13E5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F686AD4B-FC90-48B9-84C9-C7B16C2E13E5}.Debug|x64.Build.0 = Debug|Any CPU
+ {F686AD4B-FC90-48B9-84C9-C7B16C2E13E5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F686AD4B-FC90-48B9-84C9-C7B16C2E13E5}.Debug|x86.Build.0 = Debug|Any CPU
+ {F686AD4B-FC90-48B9-84C9-C7B16C2E13E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F686AD4B-FC90-48B9-84C9-C7B16C2E13E5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F686AD4B-FC90-48B9-84C9-C7B16C2E13E5}.Release|x64.ActiveCfg = Release|Any CPU
+ {F686AD4B-FC90-48B9-84C9-C7B16C2E13E5}.Release|x64.Build.0 = Release|Any CPU
+ {F686AD4B-FC90-48B9-84C9-C7B16C2E13E5}.Release|x86.ActiveCfg = Release|Any CPU
+ {F686AD4B-FC90-48B9-84C9-C7B16C2E13E5}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE