Skip to content

Instantly share code, notes, and snippets.

@xoofx
Created December 29, 2020 12:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xoofx/9faa768e04d15f25a68120fede9318ab to your computer and use it in GitHub Desktop.
Save xoofx/9faa768e04d15f25a68120fede9318ab to your computer and use it in GitHub Desktop.
Small benchmark for source generators between Scriban and Roslyn
// Requires the following packages:
// <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" />
// <PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
// <PackageReference Include="Scriban" Version="3.2.2" />
//
// BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.685 (2004/?/20H1)
// AMD Ryzen 9 3900X, 1 CPU, 24 logical and 12 physical cores
// .NET Core SDK=5.0.101
// [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT
// DefaultJob : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT
//
//
// | Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
// |------------ |-----------:|--------:|--------:|---------:|--------:|------:|----------:|
// | TestScriban | 116.8 us | 0.71 us | 0.67 us | 9.6436 | 1.2207 | - | 79.75 KB |
// | TestRoslyn | 2,931.1 us | 5.07 us | 4.74 us | 125.0000 | 42.9688 | - | 1030.5 KB |
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.Attributes;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
namespace Scriban.Benchmarks
{
[MemoryDiagnoser]
public class BenchSourceGenerator
{
private static readonly Template Template = Template.Parse(@"{{~ for cls in classes ~}}
public class Test{{ cls.name }} {
public void Property_{{cls.name}}() {
}
}
{{~ end ~}}
");
private static readonly TestClass[] Classes = Enumerable.Range(0, 100).Select(x => new TestClass(x.ToString())).ToArray();
[Benchmark]
public void TestScriban()
{
var text = Template.Render(new {classes = Classes});
}
[Benchmark]
public void TestRoslyn()
{
var classes = new List<ClassDeclarationSyntax>();
foreach (var testCls in Classes)
{
var cls = ClassDeclaration($"Test{testCls.Name}")
.WithModifiers(
TokenList(
Token(SyntaxKind.PublicKeyword)))
.WithMembers(
SingletonList<MemberDeclarationSyntax>(
MethodDeclaration(
PredefinedType(
Token(SyntaxKind.VoidKeyword)),
Identifier($"Property_{testCls.Name}"))
.WithModifiers(
TokenList(
Token(SyntaxKind.PublicKeyword)))
.WithBody(
Block())));
classes.Add(cls);
}
var text = CompilationUnit().WithMembers(List<MemberDeclarationSyntax>(classes)).NormalizeWhitespace().ToFullString();
}
private class TestClass
{
public TestClass(string name)
{
Name = name;
}
public string Name { get; set; }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment