Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// 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.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Pipelines;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
Expand Down Expand Up @@ -43,6 +45,37 @@ private void OutputFortunes(PipeWriter pipeWriter, List<Fortune> model)
// Date header
writer.Write(DateHeader.HeaderBytes);

var bodyStart = writer.Buffered;
// Body
writer.Write(_fortunesTableStart);
foreach (var item in model)
{
writer.Write(_fortunesRowStart);
writer.WriteNumeric((uint)item.Id);
writer.Write(_fortunesColumn);
HtmlEncoder.EncodeUtf8(item.Message.AsSpan(), writer.Span, out var bytesConsumed, out var bytesWritten, isFinalBlock: true);
Debug.Assert(bytesConsumed == item.Message.Length, "Not enough remaining space in the buffer");
writer.Advance(bytesWritten);
writer.Write(_fortunesRowEnd);
}
writer.Write(_fortunesTableEnd);
lengthWriter.WriteNumeric((uint)(writer.Buffered - bodyStart));

writer.Commit();
}

private void OutputFortunes(PipeWriter pipeWriter, List<FortuneDapper> model)
{
var writer = GetWriter(pipeWriter, sizeHint: 1600); // in reality it's 1361

writer.Write(_fortunesPreamble);

var lengthWriter = writer;
writer.Write(_contentLengthGap);

// Date header
writer.Write(DateHeader.HeaderBytes);

var bodyStart = writer.Buffered;
// Body
writer.Write(_fortunesTableStart);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void Advance(int count)
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(ReadOnlySpan<byte> source)
public void Write(scoped ReadOnlySpan<byte> source)
{
if (_span.Length >= source.Length)
{
Expand Down Expand Up @@ -78,7 +78,7 @@ private void EnsureMore(int count = 0)
_span = _output.GetSpan(count);
}

private void WriteMultiBuffer(ReadOnlySpan<byte> source)
private void WriteMultiBuffer(scoped ReadOnlySpan<byte> source)
{
while (source.Length > 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@ public class DapperDb
public DapperDb(AppSettings appSettings)
=> _connectionString = appSettings.ConnectionString;

public async Task<List<Fortune>> LoadFortunesRows()
public async Task<List<FortuneDapper>> LoadFortunesRows()
{
List<Fortune> result;
List<FortuneDapper> result;

using (var db = new NpgsqlConnection(_connectionString))
{
// Note: don't need to open connection if only doing one thing; let dapper do it
result = (await db.QueryAsync<Fortune>("SELECT id, message FROM fortune")).AsList();
result = (await db.QueryAsync<FortuneDapper>("SELECT id, message FROM fortune")).AsList();
}

result.Add(new Fortune(id: 0, message: "Additional fortune added at request time." ));
result.Add(new FortuneDapper(id: 0, message: "Additional fortune added at request time." ));
result.Sort();

return result;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
// 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.
// 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.

using System;

namespace PlatformBenchmarks
{
public readonly struct Fortune : IComparable<Fortune>, IComparable
{
public Fortune(int id, string message)
public Fortune(int id, byte[] message)
{
Id = id;
Message = message;
}

public int Id { get; }

public string Message { get; }
public byte[] Message { get; }

public int CompareTo(object obj) => throw new InvalidOperationException("The non-generic CompareTo should not be used");

// Performance critical, using culture insensitive comparison
public int CompareTo(Fortune other) => string.CompareOrdinal(Message, other.Message);
public int CompareTo(Fortune other) => Message.AsSpan().SequenceCompareTo(other.Message.AsSpan());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 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.

using System;

namespace PlatformBenchmarks
{
public readonly struct FortuneDapper : IComparable<FortuneDapper>, IComparable
{
public FortuneDapper(int id, string message)
{
Id = id;
Message = message;
}

public int Id { get; }

public string Message { get; }

public int CompareTo(object obj) => throw new InvalidOperationException("The non-generic CompareTo should not be used");

// Performance critical, using culture insensitive comparison
public int CompareTo(FortuneDapper other) => string.CompareOrdinal(Message, other.Message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,7 @@ public class FortuneEf : IComparable<FortuneEf>, IComparable
[Required]
public string Message { get; set; }

public int CompareTo(object obj)
{
return CompareTo((FortuneEf)obj);
}

public int CompareTo(FortuneEf other)
{
return String.CompareOrdinal(Message, other.Message);
}
public int CompareTo(object obj) => CompareTo((FortuneEf)obj);
public int CompareTo(FortuneEf other) => String.CompareOrdinal(Message, other.Message);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -255,17 +255,19 @@ public async Task<List<Fortune>> LoadFortunesRows()
result.Add(new Fortune
(
id: rdr.GetInt32(0),
message: rdr.GetString(1)
message: rdr.GetFieldValue<byte[]>(1)
));
}
}

result.Add(new Fortune(id: 0, message: "Additional fortune added at request time." ));
result.Add(new Fortune(id: 0, AdditionalFortune));
result.Sort();

return result;
}

private readonly byte[] AdditionalFortune = "Additional fortune added at request time."u8.ToArray();

private (NpgsqlCommand readCmd, NpgsqlParameter<int> idParameter) CreateReadCommand(NpgsqlConnection connection)
{
#if NET6_0_OR_GREATER
Expand Down