Rainer Stropek | @rstropek
.NET Standard
# list workloads available to install
dotnet workload search
# installs a workload
dotnet workload install
# lists installed workloads
dotnet workload list
# re-install all workloads youβve previously installed
dotnet workload repair
# update workload
dotnet workload update
# remove the specified workload if you no longer it
dotnet workload uninstallMeasure startup time of ASP.NET Core Web API with EF Core (in-memory provider) with and without ReadyToRun.
Much better startup time, more than double the file size
Without ReadyToRun:
With ReadyToRun:
// Note: Sync API, no async/await, no Task
static int DoSomethingSlow()
{
// Note async in the background
var result = Task.Run(async () =>
{
// Simulate work that takes 2 seconds (e.g. DB or net access)
await Task.Delay(TimeSpan.FromSeconds(2));
return 42;
}).Result; // Note the blocking access to the Result property here
return result;
}
| Method | Mean | Error | StdDev |
|----------------------------- |---------:|----------:|---------:|
| DeserializeJsonBlob | 3.875 ms | 0.8436 ms | 2.487 ms |
| DeserializeJsonBlobGenerated | 3.748 ms | 0.6969 ms | 2.055 ms || Method | Mean | Error | StdDev |
|----------------------------- |---------:|----------:|----------:|
| DeserializeJsonBlob | 2.694 ms | 0.0280 ms | 0.0185 ms |
| DeserializeJsonBlobGenerated | 2.773 ms | 0.0193 ms | 0.0128 ms |~3.3% improvement
No improvement
[Generator]
public class DummyGenerator : ISourceGenerator
{
/// <summary>
/// Visitor class that finds methods to generate
/// </summary>
class SyntaxReceiver : ISyntaxContextReceiver
{
...
}
public void Initialize(GeneratorInitializationContext context)
{
// Register the attribute source
context.RegisterForPostInitialization((i) => i.AddSource("GenerateAttribute", attributeText));
// Register a syntax receiver that will be created for each generation pass
context.RegisterForSyntaxNotifications(() => new SyntaxReceiver());
}
public void Execute(GeneratorExecutionContext context)
{
...
// Create string builder for source generation
var sourceBuilder = new StringBuilder();
... // Generate code
// Inject the created source into the users compilation
context.AddSource("dummy_generated.cs", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
}
}<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DummyCodeGenerator\DummyCodeGenerator.csproj"
OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<!--
Note that <TrimMode>link</TrimMode> is default in .NET 6.
See https://docs.microsoft.com/en-us/dotnet/core/deploying/trimming-options#trimming-granularity
-->
<!-- Note new support for compressing single-file bundles (expanded in-memory) -->
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\LinkerLibrary\LinkerLibrary.csproj" />
</ItemGroup>
<!--
You can prevent trimming of assemblies. There are many additional options for trimming
Read more about them at https://docs.microsoft.com/en-us/dotnet/core/deploying/trim-self-contained#prevent-assemblies-from-being-trimmed
-->
<ItemGroup>
<TrimmerRootAssembly Include="System.Text.Json" />
</ItemGroup>
</Project>
Community π€ππ
Rainer Stropek | @rstropek