Skip to content

Generated serialization should use JsonMarshal.GetRawUtf8Value extension for better perf on net9.0+ #10766

@m-nash

Description

@m-nash

The generated serializers currently emit code like this for nested model deserialization (example from AvailabilitySetData.Serialization.cs#L184 in azure-sdk-for-net):

systemData = ModelReaderWriter.Read<SystemData>(
    new BinaryData(Encoding.UTF8.GetBytes(property.Value.GetRawText())),
    ModelSerializationExtensions.WireOptions,
    AzureResourceManagerComputeContext.Default);

This pattern does two extra allocations/copies per property:

  1. GetRawText() allocates a transcoded UTF-16 string from the underlying UTF-8 bytes.
  2. Encoding.UTF8.GetBytes(...) then re-encodes that string back into a new UTF-8 byte array.

On net9.0+ we can avoid both by using JsonMarshal.GetRawUtf8Value(element), which returns the raw UTF-8 span directly from the JsonDocument backing buffer. An extension method already exists in the repo demonstrating the pattern:

https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/System.ClientModel/tests/client/ModelReaderWriter/JsonElementExtensions.cs

public static BinaryData GetUtf8Bytes(this JsonElement element)
{
#if NET9_0_OR_GREATER
    return new BinaryData(JsonMarshal.GetRawUtf8Value(element).ToArray());
#else
    return BinaryData.FromString(element.GetRawText());
#endif
}

Ask

Update the emitter so the generated deserialization code uses this extension (e.g. property.Value.GetUtf8Bytes()) instead of the Encoding.UTF8.GetBytes(GetRawText()) pattern. This will reduce allocations and improve deserialization throughput on the modern TFMs we now target.

Metadata

Metadata

Assignees

No one assigned

    Labels

    emitter:client:csharpIssue for the C# client emitter: @typespec/http-client-csharpfeatureNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions