Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.Text.Json.JsonSerializer: boxing when serialize structs #94908

Closed
vvdev opened this issue Nov 17, 2023 · 3 comments
Closed

System.Text.Json.JsonSerializer: boxing when serialize structs #94908

vvdev opened this issue Nov 17, 2023 · 3 comments
Labels

Comments

@vvdev
Copy link

vvdev commented Nov 17, 2023

Description

I noticed that JsonSerializer produces at least one boxing per every serialized struct with public properties/fields.
And maybe because of that, serialization of class instances is noticeably faster than serialization of structs with similar structure.

I was trying to implement some allocation-free processing with buffers and Utf8JsonWriter instances pooling, and found that it anyway impossible with current JsonSerializer implementation because of the boxing.
(because if i make my types i need to serialize classes, then i get rid of boxing, but instances i need to create and serialize becoming the source of allocations).

Configuration

Tested on .NET7 and .NET8

Data

Any generic or non-generic struct with public properties/fields, for example PointF or something like:

	public struct Test
	{
		private string _value;
		public string Value { get => _test; set => value; }
	}

or

	public private struct Test<T>
	{
		private T _value;
		public T Value { get => _test; set => value; }
	}

Analysis

Obviously, boxing happens (at least) in ObjectDefaultConverter, method OnTryWrite:

Wouldn't it be good to make this and related code boxing-free?

@vvdev vvdev added the tenet-performance Performance related issue label Nov 17, 2023
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Nov 17, 2023
@ghost
Copy link

ghost commented Nov 17, 2023

Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

I noticed that JsonSerializer produces at least one boxing per every serialized struct with public properties/fields.
And maybe because of that, serialization of class instances is noticeably faster than serialization of structs with similar structure.

I was trying to implement some allocation-free processing with buffers and Utf8JsonWrite instances pooling, and found that it anyway impossible with current JsonSerializer implementation because of the boxing.
(because if i make my types i need to serialize classes, then i get rid of boxing, but instances i need to create and serialize becoming the source of allocations).

Configuration

Tested on .NET7 and .NET8

Data

Any generic or non-generic struct with public properties/fields, for example PointF or something like:

	private struct Test
	{
		private string _value;
		public string Value { get => _test; set => value; }
	}

or

	private struct Test<T>
	{
		private T _value;
		public T Value { get => _test; set => value; }
	}

Analysis

Obviously, boxing happens (at least) in ObjectDefaultConverter, method OnTryWrite:

Wouldn't it be good to make this and related code boxing-free?

Author: vvdev
Assignees: -
Labels:

area-System.Text.Json, tenet-performance, untriaged

Milestone: -

@eiriktsarpalis
Copy link
Member

This is a side-effect of the current design of the JsonPropertyInfo class, which is generic only on the property type but not the declaring type. We have this issue tracking a potential improvement however there are trade-offs:

  1. It would regress the static footprint of Native AOT applications due to more generic specializations being necessary and
  2. The current design has leaked to public APIs in the case of the source generator, so we would need to author replacement APIs to make this possible.

Duplicate of #82720

@ghost ghost removed the untriaged New issue has not been triaged by the area owner label Nov 17, 2023
@vvdev
Copy link
Author

vvdev commented Nov 19, 2023

@eiriktsarpalis, thanks for explanation.

@github-actions github-actions bot locked and limited conversation to collaborators Dec 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants