diff --git a/Snappier.Benchmarks/Configuration/VersionComparisonConfig.cs b/Snappier.Benchmarks/Configuration/VersionComparisonConfig.cs index ab9dfde..89b6cf9 100644 --- a/Snappier.Benchmarks/Configuration/VersionComparisonConfig.cs +++ b/Snappier.Benchmarks/Configuration/VersionComparisonConfig.cs @@ -20,23 +20,23 @@ public VersionComparisonConfig(Job baseJob) var jobBefore48 = jobBefore.WithRuntime(ClrRuntime.Net48).AsBaseline(); var jobBefore60 = jobBefore.WithRuntime(CoreRuntime.Core60).AsBaseline(); - var jobBefore70 = jobBefore.WithRuntime(CoreRuntime.Core70).AsBaseline(); - var jobBefore70Pgo = jobBefore70.WithPgo(); + var jobBefore80 = jobBefore.WithRuntime(CoreRuntime.Core80).AsBaseline(); + var jobBefore80Pgo = jobBefore80.WithPgo(); var jobAfter48 = baseJob.WithRuntime(ClrRuntime.Net48); var jobAfter60 = baseJob.WithRuntime(CoreRuntime.Core60); - var jobAfter70 = baseJob.WithRuntime(CoreRuntime.Core70); - var jobAfter70Pgo = jobAfter70.WithPgo(); + var jobAfter80 = baseJob.WithRuntime(CoreRuntime.Core80); + var jobAfter80Pgo = jobAfter80.WithPgo(); AddJob(jobBefore48); AddJob(jobBefore60); - AddJob(jobBefore70); - AddJob(jobBefore70Pgo); + AddJob(jobBefore80); + AddJob(jobBefore80Pgo); AddJob(jobAfter48); AddJob(jobAfter60); - AddJob(jobAfter70); - AddJob(jobAfter70Pgo); + AddJob(jobAfter80); + AddJob(jobAfter80Pgo); WithOrderer(VersionComparisonOrderer.Default); @@ -53,8 +53,8 @@ public IEnumerable GetExecutionOrder(ImmutableArray p.Job.Environment.Runtime.MsBuildMoniker) .ThenBy(p => PgoColumn.IsPgo(p) ? 1 : 0) - .ThenBy(p => p.DisplayInfo) - .ThenBy(p => !p.Descriptor.Baseline); + .ThenBy(p => !p.Descriptor.Baseline) + .ThenBy(p => p.DisplayInfo); public IEnumerable GetSummaryOrder(ImmutableArray benchmarksCases, Summary summary) => diff --git a/Snappier.Benchmarks/Snappier.Benchmarks.csproj b/Snappier.Benchmarks/Snappier.Benchmarks.csproj index 9dc7308..4e1fb96 100644 --- a/Snappier.Benchmarks/Snappier.Benchmarks.csproj +++ b/Snappier.Benchmarks/Snappier.Benchmarks.csproj @@ -33,7 +33,7 @@ - + diff --git a/Snappier/Internal/Constants.cs b/Snappier/Internal/Constants.cs index 32263e3..3e62229 100644 --- a/Snappier/Internal/Constants.cs +++ b/Snappier/Internal/Constants.cs @@ -1,4 +1,6 @@ -namespace Snappier.Internal +using System; + +namespace Snappier.Internal { internal static class Constants { @@ -35,8 +37,8 @@ public enum ChunkType : byte /// (1) Extracting a byte is faster than a bit-field /// (2) It properly aligns copy offset so we do not need a <<8 /// - public static readonly ushort[] CharTable = - { + public static ReadOnlySpan CharTable => + [ 0x0001, 0x0804, 0x1001, 0x2001, 0x0002, 0x0805, 0x1002, 0x2002, 0x0003, 0x0806, 0x1003, 0x2003, 0x0004, 0x0807, 0x1004, 0x2004, 0x0005, 0x0808, 0x1005, 0x2005, 0x0006, 0x0809, 0x1006, 0x2006, @@ -69,6 +71,6 @@ public enum ChunkType : byte 0x003b, 0x0f06, 0x103b, 0x203b, 0x003c, 0x0f07, 0x103c, 0x203c, 0x0801, 0x0f08, 0x103d, 0x203d, 0x1001, 0x0f09, 0x103e, 0x203e, 0x1801, 0x0f0a, 0x103f, 0x203f, 0x2001, 0x0f0b, 0x1040, 0x2040 - }; + ]; } } diff --git a/Snappier/Internal/SnappyDecompressor.cs b/Snappier/Internal/SnappyDecompressor.cs index eade2e4..a76e01a 100644 --- a/Snappier/Internal/SnappyDecompressor.cs +++ b/Snappier/Internal/SnappyDecompressor.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.IO; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace Snappier.Internal { @@ -178,10 +179,10 @@ public static int ReadUncompressedLength(ReadOnlySpan input) internal void DecompressAllTags(ReadOnlySpan inputSpan) { - // Put Constants.CharTable on the stack to simplify lookups within the loops below. - // Slicing with length 256 here allows the JIT compiler to recognize the size is greater than - // the size of the byte we're indexing with and optimize out range checks. - ReadOnlySpan charTable = Constants.CharTable.AsSpan(0, 256); + // We only index into this array with a byte, and the list is 256 long, so it's safe to skip range checks. + // JIT doesn't seem to recognize this currently, so we'll use a ref and Unsafe.Add to avoid the checks. + Debug.Assert(Constants.CharTable.Length >= 256); + ref ushort charTable = ref MemoryMarshal.GetReference(Constants.CharTable); unchecked { @@ -323,7 +324,7 @@ internal void DecompressAllTags(ReadOnlySpan inputSpan) } else { - ushort entry = charTable[c]; + ushort entry = Unsafe.Add(ref charTable, c); // We don't use BitConverter to read because we might be reading past the end of the span // But we know that's safe because we'll be doing it in _scratch with extra data on the end.