Shipping a major vNext release of SequentialGuid (zero-alloc generation, drop obsolete API, Native AOT) #22
Merged
Conversation
CA5350 flagged SHA-1 as weak. SHA-256 gives the same perf win over SHA-512 for a 3-byte fingerprint and clears the analyzer.
…ce methods BenchmarkDotNet rejects sealed classes and static [Benchmark] methods. Suppress CA1822 in the benchmark csproj since instance methods are required by BDN.
BREAKING CHANGE: SequentialGuidGenerator and SequentialSqlGuidGenerator are removed. Use GuidV8Time.NewGuid() / GuidV8Time.NewSqlGuid() instead.
BREAKING CHANGE: GuidV7.Timestamp and GuidV8Time.Timestamp static properties are removed. Use DateTime.UtcNow directly. The struct constructors decode their Timestamp property from the generated Value (since v[prior] of PR1).
Exercises every public entry point of the core SequentialGuid package (GuidV4/V5/V7/V8Time/V8Name factory methods, SequentialGuid and SequentialSqlGuid struct ctors, SQL byte-order round-trips, JSON converter registration) and asserts each one returns a usable value. The project sets PublishAot=true and IsAotCompatible=true so trim/AOT analyzers run at build time; JSON round-trip uses a source-generated JsonSerializerContext to stay trimmer- and AOT-safe. Inherited xunit/Shouldly references from test/Directory.Build.props are stripped because this is a plain executable, not a test project. JIT run prints "AOT smoke test: PASS" and exits 0. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Major release. Three logical phases on
vNext:GuidV4,GuidV7,GuidV8Timeusestackalloc byte[16]on NET6+;GuidNameBaseddigest is stack-allocated;GuidV8Timemachine fingerprint hash switched SHA-512 → SHA-256; struct ctors stop the parallelTimestampread. Generation benchmarks now showAllocated: 0 Bon .NET 8/9/10.SequentialGuidGeneratorfamily and publicGuidV{7,8}.Timestampstatic properties. Consolidated struct-ctor disambiguation logic into internalSequentialGuidByteOrder.TryDetect. LoosenedTicksExtensions.IsDateTimeupper bound by 1 s for clock-skew slack.IsAotCompatible=trueon all four production projects. Newtest/SequentialGuid.AotSmokeTestpublishes as Native AOT and runs in CI.Breaking changes
SequentialGuidGenerator.Instance.NewGuid()→GuidV8Time.NewGuid()SequentialSqlGuidGenerator.Instance.NewSqlGuid()→GuidV8Time.NewSqlGuid()GuidV7.Timestamp/GuidV8Time.Timestamp→ useDateTime.UtcNowdirectlySequentialGuid.NodaTimeSequentialGuidGeneratorExtensions/SequentialSqlGuidGeneratorExtensionsremoved; useGuidV8TimeExtensionsinsteadWhat's in the diff
20 commits, 34 files changed, net −38 lines.
ae6df05Span overloads ·7e33751GuidV4 stackalloc ·4c550b5GuidV7 stackalloc ·3151538GuidV8Time stackalloc ·4b6a2df+15569adSHA-256 fingerprint ·559a182GuidNameBased stackalloc ·576134dstruct-ctor parallel-read removal ·999fbc8bench unsealingaac4ce9TryDetect helper ·c0e68a4struct ctors use TryDetect ·84cb07eIsDateTime slack ·3f4ff5ddelete obsolete generators ·6466428delete Timestamp properties ·ae57104delete Upgrade Guide2ce044fIsAotCompatible flags ·17de09fAOT smoke test project ·e73f5f9CI step ·ea175c8README AOT bulletaceeab8.gitignore for agent/benchmark artifactsTest plan
dotnet buildclean on all 5 TFMs (0 warnings underTreatWarningsAsErrors=true)dotnet test— 25,003 tests pass acrossnet8.0/net9.0/net10.0/net472TicksExtensionsTestscovers the 1 s slack boundary explicitly0 Ballocated forGuidV4,GuidV7,GuidV7.NewSqlGuid,GuidV8Time,GuidV8Time.NewSqlGuid(matchesGuid.NewGuidbaseline)PublishAot=trueandIsAotCompatible=true; JIT run printsAOT smoke test: PASSwindows-latestrunnerSuggested follow-ups (out of scope here)
GuidV5.Create(byte[])andGuidV8Name.Create(byte[])still allocate ~176 B per call fromIncrementalHash+Guid.ToByteArray(true). Could be addressed onNET8+ with
SHA256.HashData(ReadOnlySpan, ReadOnlySpan, Span)+Guid.TryWriteBytes(span, bigEndian: true).4b6a2dfSHA-1 attempt →15569adSHA-256 final, reverted because CA5350 flagged SHA-1 as weak).Squash-merge cleans this up if you prefer.
SequentialGuidByteOrder.TryDetect(the case where a SQL-ordered V8 GUID'sb[7]high nibbleaccidentally is 7 or 8).
References
docs/superpowers/plans/2026-05-12-sequentialguid-vnext.mddocs/superpowers/specs/2026-05-12-sequentialguid-vnext-design.md