diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/AsciiString.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/AsciiString.cs deleted file mode 100644 index 19efc541d..000000000 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/AsciiString.cs +++ /dev/null @@ -1,59 +0,0 @@ -// 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.Text; - -namespace PlatformBenchmarks -{ - public readonly struct AsciiString : IEquatable - { - private readonly byte[] _data; - - public AsciiString(string s) => _data = Encoding.ASCII.GetBytes(s); - - private AsciiString(byte[] b) => _data = b; - - public int Length => _data.Length; - - public ReadOnlySpan AsSpan() => _data; - - public static implicit operator ReadOnlySpan(AsciiString str) => str._data; - public static implicit operator byte[] (AsciiString str) => str._data; - - public static implicit operator AsciiString(string str) => new AsciiString(str); - - public override string ToString() => Encoding.ASCII.GetString(_data); - public static explicit operator string(AsciiString str) => str.ToString(); - - public bool Equals(AsciiString other) => ReferenceEquals(_data, other._data) || SequenceEqual(_data, other._data); - private bool SequenceEqual(byte[] data1, byte[] data2) => new Span(data1).SequenceEqual(data2); - - public static bool operator ==(AsciiString a, AsciiString b) => a.Equals(b); - public static bool operator !=(AsciiString a, AsciiString b) => !a.Equals(b); - public override bool Equals(object other) => (other is AsciiString) && Equals((AsciiString)other); - - public static AsciiString operator +(AsciiString a, AsciiString b) - { - var result = new byte[a.Length + b.Length]; - a._data.CopyTo(result, 0); - b._data.CopyTo(result, a.Length); - return new AsciiString(result); - } - - public override int GetHashCode() - { - // Copied from x64 version of string.GetLegacyNonRandomizedHashCode() - // https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/String.Comparison.cs - var data = _data; - int hash1 = 5381; - int hash2 = hash1; - foreach (int b in data) - { - hash1 = ((hash1 << 5) + hash1) ^ b; - } - return hash1 + (hash2 * 1566083941); - } - - } -} diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/BenchmarkApplication.Plaintext.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/BenchmarkApplication.Plaintext.cs index 8c6cf15c4..5f9edb358 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/BenchmarkApplication.Plaintext.cs +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/BenchmarkApplication.Plaintext.cs @@ -1,15 +1,17 @@ // 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 partial class BenchmarkApplication { - private readonly static AsciiString _plaintextPreamble = - _http11OK + - _headerServer + _crlf + - _headerContentTypeText + _crlf + - _headerContentLength + _plainTextBody.Length.ToString(); + private static ReadOnlySpan _plaintextPreamble => + "HTTP/1.1 200 OK\r\n"u8 + + "Server: K\r\n"u8 + + "Content-Type: text/plain\r\n"u8 + + "Content-Length: 13"u8; private static void PlainText(ref BufferWriter writer) { diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/BenchmarkApplication.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/BenchmarkApplication.cs index e64048461..5d1f8b541 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/BenchmarkApplication.cs +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/BenchmarkApplication.cs @@ -14,28 +14,29 @@ namespace PlatformBenchmarks { - public partial class BenchmarkApplication + public sealed partial class BenchmarkApplication { - private readonly static AsciiString _applicationName = "Kestrel Platform-Level Application"; - public static AsciiString ApplicationName => _applicationName; - - private readonly static AsciiString _crlf = "\r\n"; - private readonly static AsciiString _http11OK = "HTTP/1.1 200 OK\r\n"; - private readonly static AsciiString _http11NotFound = "HTTP/1.1 404 Not Found\r\n"; - private readonly static AsciiString _headerServer = "Server: K"; - private readonly static AsciiString _headerContentLength = "Content-Length: "; - private readonly static AsciiString _headerContentLengthZero = "Content-Length: 0"; - private readonly static AsciiString _headerContentTypeText = "Content-Type: text/plain"; - private readonly static AsciiString _headerContentTypeJson = "Content-Type: application/json"; - - private readonly static AsciiString _dbPreamble = - _http11OK + - _headerServer + _crlf + - _headerContentTypeJson + _crlf + - _headerContentLength; - - private readonly static AsciiString _plainTextBody = "Hello, World!"; - private readonly static AsciiString _contentLengthGap = new string(' ', 4); + public static ReadOnlySpan ApplicationName => "Kestrel Platform-Level Application"u8; + + private static ReadOnlySpan _crlf => "\r\n"u8; + private static ReadOnlySpan _eoh => "\r\n\r\n"u8; // End Of Headers + private static ReadOnlySpan _http11OK => "HTTP/1.1 200 OK\r\n"u8; + private static ReadOnlySpan _http11NotFound => "HTTP/1.1 404 Not Found\r\n"u8; + private static ReadOnlySpan _headerServer => "Server: K"u8; + private static ReadOnlySpan _headerContentLength => "Content-Length: "u8; + private static ReadOnlySpan _headerContentLengthZero => "Content-Length: 0"u8; + private static ReadOnlySpan _headerContentTypeText => "Content-Type: text/plain"u8; + private static ReadOnlySpan _headerContentTypeJson => "Content-Type: application/json"u8; + private static ReadOnlySpan _headerContentTypeHtml => "Content-Type: text/html; charset=UTF-8"u8; + + private static ReadOnlySpan _dbPreamble => + "HTTP/1.1 200 OK\r\n"u8 + + "Server: K\r\n"u8 + + "Content-Type: application/json\r\n"u8 + + "Content-Length: "u8; + + private static ReadOnlySpan _plainTextBody => "Hello, World!"u8; + private static ReadOnlySpan _contentLengthGap => " "u8; public static RawDb RawDb { get; set; } public static DapperDb DapperDb { get; set; } @@ -74,15 +75,15 @@ private partial class JsonContext : JsonSerializerContext public static class Paths { - public readonly static AsciiString Json = "/json"; - public readonly static AsciiString Plaintext = "/plaintext"; - public readonly static AsciiString SingleQuery = "/db"; - public readonly static AsciiString FortunesRaw = "/fortunes"; - public readonly static AsciiString FortunesDapper = "/fortunes/dapper"; - public readonly static AsciiString FortunesEf = "/fortunes/ef"; - public readonly static AsciiString Updates = "/updates/"; - public readonly static AsciiString MultipleQueries = "/queries/"; - public readonly static AsciiString Caching = "/cached-worlds/"; + public static ReadOnlySpan Json => "/json"u8; + public static ReadOnlySpan Plaintext => "/plaintext"u8; + public static ReadOnlySpan SingleQuery => "/db"u8; + public static ReadOnlySpan FortunesRaw => "/fortunes"u8; + public static ReadOnlySpan FortunesDapper => "/fortunes/dapper"u8; + public static ReadOnlySpan FortunesEf => "/fortunes/ef"u8; + public static ReadOnlySpan Updates => "/updates/"u8; + public static ReadOnlySpan MultipleQueries => "/queries/"u8; + public static ReadOnlySpan Caching => "/cached-worlds/"u8; } private RequestType _requestType; @@ -191,11 +192,11 @@ private static Task Default(PipeWriter pipeWriter) return Task.CompletedTask; } #endif - private readonly static AsciiString _defaultPreamble = - _http11NotFound + - _headerServer + _crlf + - _headerContentTypeText + _crlf + - _headerContentLengthZero; + private static ReadOnlySpan _defaultPreamble => + "HTTP/1.1 200 OK\r\n"u8 + + "Server: K"u8 + "\r\n"u8 + + "Content-Type: text/plain"u8 + + "Content-Length: 0"u8; private static void Default(ref BufferWriter writer) { diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Configuration/AppSettings.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Configuration/AppSettings.cs index 259cf5a34..090e21238 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Configuration/AppSettings.cs +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Configuration/AppSettings.cs @@ -3,7 +3,7 @@ namespace PlatformBenchmarks { - public class AppSettings + public sealed class AppSettings { public string ConnectionString { get; set; } diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/BatchUpdateString.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/BatchUpdateString.cs index 83b26ef8f..85273692b 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/BatchUpdateString.cs +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/BatchUpdateString.cs @@ -6,7 +6,7 @@ namespace PlatformBenchmarks { - internal class BatchUpdateString + internal sealed class BatchUpdateString { private const int MaxBatch = 500; diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/DapperDb.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/DapperDb.cs index b610c1a39..d3c738f4b 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/DapperDb.cs +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/DapperDb.cs @@ -6,7 +6,7 @@ namespace PlatformBenchmarks { - public class DapperDb + public sealed class DapperDb { private readonly string _connectionString; diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/EfDb.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/EfDb.cs index 86a2c9e13..0f2a97de9 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/EfDb.cs +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/EfDb.cs @@ -7,7 +7,7 @@ namespace PlatformBenchmarks { - public class EfDb + public sealed class EfDb { private static PooledDbContextFactory _dbContextFactory; diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/FortuneEf.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/FortuneEf.cs index c9466c892..9e78d4fbc 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/FortuneEf.cs +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/FortuneEf.cs @@ -6,7 +6,7 @@ namespace PlatformBenchmarks { [Table("fortune")] - public class FortuneEf : IComparable, IComparable + public sealed class FortuneEf : IComparable, IComparable { [Column("id")] public int Id { get; set; } diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/Random.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/Random.cs index 9cb3ef4c3..19daabd05 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/Random.cs +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/Random.cs @@ -7,7 +7,7 @@ namespace PlatformBenchmarks { - public class ConcurrentRandom + public sealed class ConcurrentRandom { private static int nextSeed = 0; diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/RawDb.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/RawDb.cs index 9f83617dc..58b1523fb 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/RawDb.cs +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Data/RawDb.cs @@ -13,7 +13,7 @@ namespace PlatformBenchmarks { - public class RawDb + public sealed class RawDb { private readonly ConcurrentRandom _random; private readonly MemoryCache _cache diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/DateHeader.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/DateHeader.cs index 6804f572f..c405eb2af 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/DateHeader.cs +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/DateHeader.cs @@ -28,7 +28,7 @@ internal static class DateHeader static DateHeader() { - var utf8 = Encoding.ASCII.GetBytes("\r\nDate: ").AsSpan(); + var utf8 = "\r\nDate: "u8; utf8.CopyTo(s_headerBytesMaster); utf8.CopyTo(s_headerBytesScratch); @@ -61,9 +61,7 @@ private static void SetDateValues(DateTimeOffset value) throw new Exception("date time format failed"); } Debug.Assert(written == dateTimeRLength); - var temp = s_headerBytesMaster; - s_headerBytesMaster = s_headerBytesScratch; - s_headerBytesScratch = temp; + (s_headerBytesScratch, s_headerBytesMaster) = (s_headerBytesMaster, s_headerBytesScratch); } } } diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/HttpApplication.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/HttpApplication.cs index 48c736ab2..c5d572e40 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/HttpApplication.cs +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/HttpApplication.cs @@ -14,7 +14,7 @@ public static class HttpApplicationConnectionBuilderExtensions } } - public class HttpApplication where TConnection : IHttpConnection, new() + public sealed class HttpApplication where TConnection : IHttpConnection, new() { public Task ExecuteAsync(ConnectionContext connection) { diff --git a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Program.cs b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Program.cs index a1a6f1a6f..db4e79ec9 100644 --- a/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Program.cs +++ b/src/BenchmarksApps/TechEmpower/PlatformBenchmarks/Program.cs @@ -3,6 +3,7 @@ using System; using System.Runtime.InteropServices; +using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; @@ -20,17 +21,17 @@ public static async Task Main(string[] args) { Args = args; - Console.WriteLine(BenchmarkApplication.ApplicationName); + Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.ApplicationName)); #if !DATABASE - Console.WriteLine(BenchmarkApplication.Paths.Plaintext); - Console.WriteLine(BenchmarkApplication.Paths.Json); + Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.Plaintext)); + Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.Json)); #else - Console.WriteLine(BenchmarkApplication.Paths.FortunesRaw); - Console.WriteLine(BenchmarkApplication.Paths.FortunesDapper); - Console.WriteLine(BenchmarkApplication.Paths.FortunesEf); - Console.WriteLine(BenchmarkApplication.Paths.SingleQuery); - Console.WriteLine(BenchmarkApplication.Paths.Updates); - Console.WriteLine(BenchmarkApplication.Paths.MultipleQueries); + Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.FortunesRaw)); + Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.FortunesDapper)); + Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.FortunesEf)); + Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.SingleQuery)); + Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.Updates)); + Console.WriteLine(Encoding.UTF8.GetString(BenchmarkApplication.Paths.MultipleQueries)); #endif DateHeader.SyncDateTimer();