Repository navigation
Remote: PrimitiveSerializers as a native SerializerV2 (same id 17, same bytes) - #8719
Merged
Aaronontheweb merged 2 commits intoOct 2, 2026
Merged
Conversation
…me bytes) Derive PrimitiveSerializers from SerializerV2. Strings encode straight into the writer's span, ints and longs use BinaryPrimitives little-endian, and SizeHint is exact. Deserialize reads all nine manifest spellings from a ReadOnlySequence, including multi-segment input. ToBinary stays a single exact-size allocation. Wire format, id, manifests and use-legacy-behavior are unchanged. Golden-byte specs captured from the previous implementation lock that in. The API approval files record the new base class.
Measure serialize-into-writer, ToBinary, Deserialize and FromBinary for short and 1 KB strings, int and long.
This was referenced Oct 7, 2026
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.
Part of #8675.
Summary
PrimitiveSerializers(id 17) now derives fromSerializerV2instead ofSerializerWithStringManifest. It writes the same bytes under the same id.Serializewrites into the caller'sIBufferWriter<byte>. Strings encode UTF-8 straight intowriter.GetSpan(byteCount). Ints and longs useBinaryPrimitiveslittle-endian.SizeHintis exact:Encoding.UTF8.GetByteCount(s), 4, 8.Deserializereads from aReadOnlySequence<byte>. Single-segment input takes a fast path. Multi-segment ints and longs copy into a stack buffer. Multi-segment strings decode withEncoding.UTF8.GetString(in ReadOnlySequence<byte>), so no joined copy.ToBinaryis overridden. TheSerializerV2base allocates anArrayBufferWriterand copies, which would slow persistence journals and classic remoting. The override stays one exact-size allocation, as before.FromBinary(byte[], string)uses the base. It wraps the array in aReadOnlySequencestruct and shows no change in the benchmark.Why
The format is already minimal. The cost was the API. Artery reached this serializer through the V1 adapter, which called
ToBinary, allocated abyte[]and copied it into the frame. Artery now gets the serializer itself.What stays the same
primitivealias. The module table row inRemoteSerializers.csis untouched.BitConverterused machine byte order. All supported .NET platforms are little-endian, so little-endian is the same format.S/I/L, the .NET Core names and the .NET Framework names. An unknown manifest throws the sameArgumentException.use-legacy-behavior:onreturns the type-qualified name,offreturnsS/I/Land rejects other types.Manifestis unchanged.ConfigurationExceptionon null config, and the error text for unsupported types.BitConverter.ToInt32(bytes, 0). Input that is too short throwsArgumentException(aBitConvertercall threw the same type or a subclass).Tests
PrimitiveSerializersSpec:SerializeandToBinaryboth match.FromBinary(byte[])andDeserialize(ReadOnlySequence).SizeHintequals the bytes written.FindSerializerV2Forreturns thePrimitiveSerializersinstance itself (no adapter) for string, int and long.use-legacy-behavioron and off manifests, unsupported types, null config.Also run:
Akka.Remote.Testsin full (814 passed, 5 skipped, 0 failed),Akka.Tests --filter Serializ(150 passed, 1 skipped),Akka.API.Tests(24 passed),dotnet build Akka.slnx -c Release -warnaserror(0 warnings).Benchmark
PrimitiveSerializerBenchmarksis new. Short job (--job short: 3 warmup, 3 iterations, 1 launch), .NET 10.0.11, i9-9900K, Linux. A ShortRun has wide error bars, so read these as direction, not exact ratios. "Before" isdev; itsSerializeToWriterandDeserializeFromSequencego through the V1 adapter, the way Artery reached it.The writer path no longer allocates. The
byte[]paths (ToBinary,FromBinary) allocate the same as before, as intended.Breaking changes
PrimitiveSerializerschanges its base class fromSerializerWithStringManifesttoSerializerV2. Code that casts it toSerializerWithStringManifest, or that relies on members only that base declares, breaks at compile time and at run time.SerializerV2still derives fromSerializer, so code that uses it as aSerializeris unaffected.CoreAPISpec.ApproveRemote.*.verified.txt) record the new base class and the newDeserialize,SerializeandSizeHintmembers.Closes #8688