Skip to content

Commit

Permalink
Reduce JIT'ed Code Size and Optimize (#421)
Browse files Browse the repository at this point in the history
- Remove `IMethodNameResolver`
- Remove most custom strings from generated code
- Rethink how we apply `checked` statements
- Fix `FSThrow` statements to be more efficient
- String serialization is no longer inlined
  • Loading branch information
jamescourtney authored Feb 20, 2024
1 parent a1fad43 commit 6acaf8f
Show file tree
Hide file tree
Showing 60 changed files with 618 additions and 537 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
/src/Tests/FlatSharpEndToEndTests/FlatSharp.generated.cs
/src/Benchmarks/ExperimentalBenchmark/FlatSharp.generated.cs
/src/Tests/FlatSharpEndToEndTests_Generated/FlatSharpEndToEndTestsGenerated.xml
**/BenchmarkDotNet.Artifacts/**
2 changes: 1 addition & 1 deletion src/Benchmarks/Benchmark/Benchmark.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<TargetFrameworks>net8.0</TargetFrameworks>
<DelaySign>false</DelaySign>
<SignAssembly>false</SignAssembly>
<DefineConstants>$(DefineContants);CURRENT_VERSION_ONLY;FLATSHARP_7_0_0_OR_GREATER</DefineConstants>
<DefineConstants>$(DefineContants);CURRENT_VERSION_ONLY;RUN_COMPARISON_BENCHMARKS;FLATSHARP_7_0_0_OR_GREATER</DefineConstants>
</PropertyGroup>

<ItemGroup>
Expand Down
32 changes: 32 additions & 0 deletions src/Benchmarks/BenchmarkOld/BenchmarkOld.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\common.props" />

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net8.0</TargetFrameworks>
<DelaySign>false</DelaySign>
<SignAssembly>false</SignAssembly>
<DefineConstants>$(DefineContants);FLATSHARP_7_0_0_OR_GREATER</DefineConstants>
</PropertyGroup>

<ItemGroup>
<Compile Include="../Benchmark/*.cs" />
<Compile Include="../Benchmark/FBBench/*.cs" />
<Compile Include="../Benchmark/Internal/*.cs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.10" />
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.13.10" />
<PackageReference Include="MessagePack" Version="2.5.140" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="protobuf-net" Version="3.2.30" />
<PackageReference Include="FlatSharp" Version="7.4.0" />
<PackageReference Include="FlatSharp.Runtime" Version="7.4.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Google.FlatBuffers\Google.FlatBuffers.csproj" />
</ItemGroup>

</Project>
33 changes: 33 additions & 0 deletions src/Benchmarks/ExperimentalBenchmark/Benchmark.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ attribute "fs_unsafeExternal";
attribute "fs_memoryMarshal";
attribute "fs_vector";
attribute "fs_writeThrough";
attribute "fs_sharedString";

namespace BenchmarkCore;

Expand Down Expand Up @@ -39,3 +40,35 @@ table FooBarContainer (fs_serializer) {
fruit:short;
location:string;
}

table LotsOfStrings (fs_serializer) {
list : [ string ];
}

table MultiTable (fs_serializer)
{
A : A;
B : B;
C : C;
D : D;
E : E;
F : F;
G : G;
H : H;
I : I;
J : J;
K : K;
}

table A { Value : string; }
table B { Value : string; }
table C { Value : string; }
table D { Value : string; }
table E { Value : string; }
table F { Value : string; }
table G { Value : string; }
table H { Value : string; Value2 : string; Value3 : string; }
table I { Value : string; }
table J { Value : string; }
table K { Value : string; }

55 changes: 54 additions & 1 deletion src/Benchmarks/ExperimentalBenchmark/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Environments;
Expand All @@ -36,6 +37,13 @@ public class Program
private FooBarContainer container;
private byte[] buffer;

private LotsOfStrings strings;

private MultiTable multi;

public static readonly int A = 3;
public static readonly int B = 4;

[GlobalSetup]
public void Setup()
{
Expand Down Expand Up @@ -66,6 +74,28 @@ public void Setup()
};

this.buffer = new byte[1024 * 1024];

this.multi = new()
{
A = new() { Value = Guid.NewGuid().ToString() },
B = new() { Value = Guid.NewGuid().ToString() },
C = new() { Value = Guid.NewGuid().ToString() },
D = new() { Value = Guid.NewGuid().ToString() },
E = new() { Value = Guid.NewGuid().ToString() },
F = new() { Value = Guid.NewGuid().ToString() },
G = new() { Value = Guid.NewGuid().ToString() },
H = new() { Value = Guid.NewGuid().ToString(), Value2 = Guid.NewGuid().ToString(), Value3 = Guid.NewGuid().ToString(), },
I = new() { Value = Guid.NewGuid().ToString() },
J = new() { Value = Guid.NewGuid().ToString() },
K = new() { Value = Guid.NewGuid().ToString() },
};

this.strings = new LotsOfStrings
{
List = Enumerable.Range(0, 100).Select(x => Guid.NewGuid().ToString()).ToList()
};

this.Serialize();
}

[Benchmark]
Expand All @@ -74,9 +104,32 @@ public void Serialize()
FooBarContainer.Serializer.Write(this.buffer, this.container);
}

[Benchmark]
public string Parse()
{
return FooBarContainer.Serializer.Parse(this.buffer).Location;
}

public static void Main(string[] args)
{
BenchmarkRunner.Run(typeof(Program).Assembly);
Job job = Job.ShortRun
.WithAnalyzeLaunchVariance(true)
.WithLaunchCount(1)
.WithWarmupCount(5)
.WithIterationCount(10)
.WithRuntime(CoreRuntime.Core80)
/*.WithEnvironmentVariable(new("DOTNET_JitDisasmOnlyOptimized", "1"))
.WithEnvironmentVariable(new EnvironmentVariable("DOTNET_JitDisasmSummary", "1"))
.WithEnvironmentVariable(new EnvironmentVariable("DOTNET_JitStdOutFile", $"d:\\out.txt"))*/
.WithEnvironmentVariable(new EnvironmentVariable("fake", $"fake"));

var config = DefaultConfig.Instance
.AddColumn(new[] { StatisticColumn.P25, StatisticColumn.P95 })
.AddDiagnoser(MemoryDiagnoser.Default)
.AddDiagnoser(new DisassemblyDiagnoser(new DisassemblyDiagnoserConfig()))
.AddJob(job);

BenchmarkRunner.Run(typeof(Program).Assembly, config);
}
}
}
2 changes: 1 addition & 1 deletion src/FlatSharp.Compiler/SchemaModel/RootModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ private static void WriteHelperClass(Type type, CompileContext context, CodeWrit
{
var options = new FlatBufferSerializerOptions();
var generator = new RoslynSerializerGenerator(options, context.TypeModelContainer);
string helper = generator.ImplementHelperClass(context.TypeModelContainer.CreateTypeModel(type), new DefaultMethodNameResolver(), context.Options.Deserializers);
string helper = generator.ImplementHelperClass(context.TypeModelContainer.CreateTypeModel(type), context.Options.Deserializers);

writer.AppendLine(helper);
}
Expand Down
3 changes: 1 addition & 2 deletions src/FlatSharp.Compiler/SchemaModel/TableSchemaModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@ protected override void EmitExtraData(CodeWriter writer, CompileContext context)
{
if (this.Attributes.DeserializationOption is not null && context.CompilePass >= CodeWritingPass.SerializerAndRpcGeneration)
{
DefaultMethodNameResolver resolver = new();
ITypeModel model = context.TypeModelContainer.CreateTypeModel(context.PreviousAssembly!.GetType(this.FullName)!);
(string ns, string name) = resolver.ResolveGeneratedSerializerClassName(model);
(string ns, string name) = DefaultMethodNameResolver.ResolveGeneratedSerializerClassName(model);

string optionTypeName = typeof(FlatBufferDeserializationOption).GetGlobalCompilableTypeName();

Expand Down
9 changes: 7 additions & 2 deletions src/FlatSharp.Compiler/SchemaModel/ValueUnionSchemaModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ protected override void OnWriteCode(CodeWriter writer, CompileContext context)
writer.AppendLine($"if (this.Discriminator != {item.value.Value})");
using (writer.WithBlock())
{
writer.AppendLine($"{typeof(FSThrow).GGCTN()}.{nameof(FSThrow.InvalidOperation)}(\"Union Discriminator != {item.value.Value}\");");
writer.AppendLine($"{typeof(FSThrow).GGCTN()}.{nameof(FSThrow.InvalidOperation_UnionIsNotOfType)}();");
}

writer.AppendLine($"return this.UncheckedGetItem{item.value.Value}();");
Expand Down Expand Up @@ -257,7 +257,12 @@ private void WriteAcceptMethod(
writer.AppendLine($"case {index}: return visitor.Visit(this.UncheckedGetItem{item.value.Value}());");
}

writer.AppendLine($"default: return {typeof(FSThrow).GGCTN()}.{nameof(FSThrow.InvalidOperation)}<TReturn>(\"Unexpected discriminator\");");
writer.AppendLine($"default:");
using (writer.IncreaseIndent())
{
writer.AppendLine($"{typeof(FSThrow).GGCTN()}.{nameof(FSThrow.InvalidOperation_InvalidUnionDiscriminator)}<{this.Name}>(disc);");
writer.AppendLine("return default(TReturn);");
}
}
}
}
Expand Down
Loading

0 comments on commit 6acaf8f

Please sign in to comment.