Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frameworks/CSharp/aspnetcore/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ See [.NET Core](http://dot.net) and [ASP.NET Core](https://github.com/dotnet/asp

**Language**

* C# 8.0
* C# 13.0

1 change: 1 addition & 0 deletions frameworks/CSharp/aspnetcore/benchmark_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"json_url": "/json",
"db_url": "/db",
"query_url": "/queries/",
"fortune_url": "/fortunes",
"update_url": "/updates/",
"cached_query_url": "/cached-worlds/",
"port": 8080,
Expand Down
2 changes: 1 addition & 1 deletion frameworks/CSharp/aspnetcore/src/Minimal/Minimal.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Npgsql" Version="8.0.5" />
<PackageReference Include="Npgsql" Version="9.0.2" />
<PackageReference Include="Dapper" Version="2.1.35" />
<PackageReference Include="RazorSlices" Version="0.8.1" />
</ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions frameworks/CSharp/aspnetcore/src/Mvc/Mvc.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Npgsql" Version="8.0.5" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.0-rc.2" />
<PackageReference Include="Npgsql" Version="9.0.2" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.2" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace PlatformBenchmarks;

public partial class BenchmarkApplication
public sealed partial class BenchmarkApplication
{
private static async Task Caching(PipeWriter pipeWriter, int count)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

#if !AOT
using System;
using System.IO.Pipelines;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using RazorSlices;

namespace PlatformBenchmarks;

public partial class BenchmarkApplication
public sealed partial class BenchmarkApplication
{
private async Task FortunesRaw(PipeWriter pipeWriter)
{
Expand All @@ -19,7 +19,7 @@ await RawDb.LoadFortunesRows(),
FortunesTemplateFactory);
}

private ValueTask OutputFortunes<TModel>(PipeWriter pipeWriter, TModel model, SliceFactory<TModel> templateFactory)
private ValueTask OutputFortunes<TModel>(PipeWriter pipeWriter, TModel model, Func<TModel, RazorSlice<TModel>> templateFactory)
{
// Render headers
var preamble = """
Expand All @@ -39,7 +39,7 @@ private ValueTask OutputFortunes<TModel>(PipeWriter pipeWriter, TModel model, Sl
// Kestrel PipeWriter span size is 4K, headers above already written to first span & template output is ~1350 bytes,
// so 2K chunk size should result in only a single span and chunk being used.
var chunkedWriter = GetChunkedWriter(pipeWriter, chunkSizeHint: 2048);
var renderTask = template.RenderAsync(chunkedWriter, null, HtmlEncoder);
var renderTask = template.RenderAsync(chunkedWriter, HtmlEncoder);

if (renderTask.IsCompletedSuccessfully)
{
Expand All @@ -51,18 +51,17 @@ private ValueTask OutputFortunes<TModel>(PipeWriter pipeWriter, TModel model, Sl
return AwaitTemplateRenderTask(renderTask, chunkedWriter, template);
}

private static async ValueTask AwaitTemplateRenderTask(ValueTask renderTask, ChunkedBufferWriter<WriterAdapter> chunkedWriter, RazorSlice template)
private static async ValueTask AwaitTemplateRenderTask(ValueTask renderTask, ChunkedPipeWriter chunkedWriter, RazorSlice template)
{
await renderTask;
EndTemplateRendering(chunkedWriter, template);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void EndTemplateRendering(ChunkedBufferWriter<WriterAdapter> chunkedWriter, RazorSlice template)
private static void EndTemplateRendering(ChunkedPipeWriter chunkedWriter, RazorSlice template)
{
chunkedWriter.End();
chunkedWriter.Complete();
ReturnChunkedWriter(chunkedWriter);
template.Dispose();
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace PlatformBenchmarks;

public partial class BenchmarkApplication : IHttpConnection
public sealed partial class BenchmarkApplication : IHttpConnection
{
private State _state;

Expand Down Expand Up @@ -193,15 +193,15 @@ private static BufferWriter<WriterAdapter> GetWriter(PipeWriter pipeWriter, int
=> new(new(pipeWriter), sizeHint);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ChunkedBufferWriter<WriterAdapter> GetChunkedWriter(PipeWriter pipeWriter, int chunkSizeHint)
private static ChunkedPipeWriter GetChunkedWriter(PipeWriter pipeWriter, int chunkSizeHint)
{
var writer = ChunkedWriterPool.Get();
writer.SetOutput(new WriterAdapter(pipeWriter), chunkSizeHint);
writer.SetOutput(pipeWriter, chunkSizeHint);
return writer;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ReturnChunkedWriter(ChunkedBufferWriter<WriterAdapter> writer) => ChunkedWriterPool.Return(writer);
private static void ReturnChunkedWriter(ChunkedPipeWriter writer) => ChunkedWriterPool.Return(writer);

private struct WriterAdapter : IBufferWriter<byte>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace PlatformBenchmarks;

public partial class BenchmarkApplication
public sealed partial class BenchmarkApplication
{
private readonly static uint _jsonPayloadSize = (uint)JsonSerializer.SerializeToUtf8Bytes(
new JsonMessage { message = "Hello, World!" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace PlatformBenchmarks;

public partial class BenchmarkApplication
public sealed partial class BenchmarkApplication
{
private static async Task MultipleQueries(PipeWriter pipeWriter, int count)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace PlatformBenchmarks;

public partial class BenchmarkApplication
public sealed partial class BenchmarkApplication
{
private static ReadOnlySpan<byte> _plaintextPreamble =>
"HTTP/1.1 200 OK\r\n"u8 +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace PlatformBenchmarks;

public partial class BenchmarkApplication
public sealed partial class BenchmarkApplication
{
private static async Task SingleQuery(PipeWriter pipeWriter)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace PlatformBenchmarks;

public partial class BenchmarkApplication
public sealed partial class BenchmarkApplication
{
private static async Task Updates(PipeWriter pipeWriter, int count)
{
Expand Down
19 changes: 7 additions & 12 deletions frameworks/CSharp/aspnetcore/src/Platform/BenchmarkApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.Extensions.ObjectPool;
#if !AOT
using Platform.Templates;
using RazorSlices;
#endif

namespace PlatformBenchmarks
{
Expand Down Expand Up @@ -42,26 +41,24 @@ public sealed partial class BenchmarkApplication

public static RawDb RawDb { get; set; }

private static readonly DefaultObjectPool<ChunkedBufferWriter<WriterAdapter>> ChunkedWriterPool
private static readonly DefaultObjectPool<ChunkedPipeWriter> ChunkedWriterPool
= new(new ChunkedWriterObjectPolicy());

private sealed class ChunkedWriterObjectPolicy : IPooledObjectPolicy<ChunkedBufferWriter<WriterAdapter>>
private sealed class ChunkedWriterObjectPolicy : IPooledObjectPolicy<ChunkedPipeWriter>
{
public ChunkedBufferWriter<WriterAdapter> Create() => new();
public ChunkedPipeWriter Create() => new();

public bool Return(ChunkedBufferWriter<WriterAdapter> writer)
public bool Return(ChunkedPipeWriter writer)
{
writer.Reset();
return true;
}
}

#if !AOT
#if NPGSQL
private readonly static SliceFactory<List<FortuneUtf8>> FortunesTemplateFactory = RazorSlice.ResolveSliceFactory<List<FortuneUtf8>>("/Templates/FortunesUtf8.cshtml");
private readonly static Func<List<FortuneUtf8>, RazorSlice<List<FortuneUtf8>>> FortunesTemplateFactory = FortunesUtf8.Create;
#else
private readonly static SliceFactory<List<FortuneUtf16>> FortunesTemplateFactory = RazorSlice.ResolveSliceFactory<List<FortuneUtf16>>("/Templates/FortunesUtf16.cshtml");
#endif
private readonly static Func<List<FortuneUtf16>, RazorSlice<List<FortuneUtf16>>> FortunesTemplateFactory = FortunesUtf16.Create;
#endif

[ThreadStatic]
Expand Down Expand Up @@ -167,9 +164,7 @@ private bool ProcessRequest(ref BufferWriter<WriterAdapter> writer)

private Task ProcessRequestAsync() => _requestType switch
{
#if !AOT
RequestType.FortunesRaw => FortunesRaw(Writer),
#endif
RequestType.SingleQuery => SingleQuery(Writer),
RequestType.Caching => Caching(Writer, _queries),
RequestType.Updates => Updates(Writer, _queries),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@
using System.Buffers;
using System.Buffers.Text;
using System.Diagnostics;
using System.IO.Pipelines;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;

namespace PlatformBenchmarks;

internal sealed class ChunkedBufferWriter<TWriter> : IBufferWriter<byte> where TWriter : IBufferWriter<byte>
internal sealed class ChunkedPipeWriter : PipeWriter
{
private const int DefaultChunkSizeHint = 2048;
private static readonly StandardFormat DefaultHexFormat = GetHexFormat(DefaultChunkSizeHint);
private static ReadOnlySpan<byte> ChunkTerminator => "\r\n"u8;

private TWriter _output;
private PipeWriter _output;
private int _chunkSizeHint;
private StandardFormat _hexFormat = DefaultHexFormat;
private Memory<byte> _currentFullChunk;
Expand All @@ -26,12 +29,12 @@ internal sealed class ChunkedBufferWriter<TWriter> : IBufferWriter<byte> where T

public Memory<byte> Memory => _currentChunk;

public TWriter Output => _output;
public PipeWriter Output => _output;

public int Buffered => _buffered;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetOutput(TWriter output, int chunkSizeHint = DefaultChunkSizeHint)
public void SetOutput(PipeWriter output, int chunkSizeHint = DefaultChunkSizeHint)
{
_buffered = 0;
_chunkSizeHint = chunkSizeHint;
Expand All @@ -51,16 +54,20 @@ public void Reset()
_currentChunk = default;
}

public override bool CanGetUnflushedBytes => _output.CanGetUnflushedBytes;

public override long UnflushedBytes => _output.UnflushedBytes;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Advance(int count)
public override void Advance(int count)
{
ThrowIfEnded();

_buffered += count;
_currentChunk = _currentChunk[count..];
}

public Memory<byte> GetMemory(int sizeHint = 0)
public override Memory<byte> GetMemory(int sizeHint = 0)
{
ThrowIfEnded();

Expand All @@ -71,9 +78,14 @@ public Memory<byte> GetMemory(int sizeHint = 0)
return _currentChunk;
}

public Span<byte> GetSpan(int sizeHint = 0) => GetMemory(sizeHint).Span;
public override Span<byte> GetSpan(int sizeHint = 0) => GetMemory(sizeHint).Span;

public override void CancelPendingFlush()
{
_output.CancelPendingFlush();
}

public void End()
public override void Complete(Exception exception = null)
{
ThrowIfEnded();

Expand All @@ -82,6 +94,11 @@ public void End()
_ended = true;
}

public override ValueTask<FlushResult> FlushAsync(CancellationToken cancellationToken = default)
{
return _output.FlushAsync(cancellationToken);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static StandardFormat GetHexFormat(int maxValue)
{
Expand Down
8 changes: 2 additions & 6 deletions frameworks/CSharp/aspnetcore/src/Platform/Platform.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
<IsTestAssetProject>true</IsTestAssetProject>
<LangVersion>preview</LangVersion>
<UserSecretsId>38063504-d08c-495a-89c9-daaad2f60f31</UserSecretsId>
<DefineConstants Condition="'$(PublishAot)' == 'true'">AOT;$(DefineConstants)</DefineConstants>
</PropertyGroup>

<PropertyGroup>
Expand All @@ -19,15 +18,12 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Npgsql" Version="8.0.5" />
<PackageReference Include="Npgsql" Version="9.0.2" />
<PackageReference Include="MySqlConnector" Version="2.3.7" />
<PackageReference Include="Dapper" Version="2.1.35" />
<PackageReference Include="RazorSlices" Version="0.7.0" Condition="$(PublishAot) != 'true'" />
<PackageReference Include="RazorSlices" Version="0.8.1" />
</ItemGroup>

<PropertyGroup Condition="$(PublishAot) == 'true'">
<DefaultItemExcludes>$(MSBuildThisFileDirectory)Templates/**;$(DefaultItemExcludes)</DefaultItemExcludes>
</PropertyGroup>
<ItemGroup Condition="$(PublishAot) == 'true'">
<RuntimeHostConfigurationOption Include="System.Threading.ThreadPool.HillClimbing.Disable" Value="true" />
</ItemGroup>
Expand Down
Loading