Laden...

Json -> Unity3D

Erstellt von Yeats vor einem Jahr Letzter Beitrag vor einem Jahr 777 Views
Y
Yeats Themenstarter:in
102 Beiträge seit 2005
vor einem Jahr
Json -> Unity3D

Verwendetes Datenbanksystem: json

Hallo

Arbeite an einem Unity3D Projekt, welches nach WebGL übersetzt wird, und einen Produktkatalog abbilden soll.

Das Projekt empfängt einen JSON-String (~4MB) der deserialisiert werden muss, um die interne Datenstruktur aufbauen zu können.
Dieser JSON-String besteht dabei aus einem Teil, der von mir kontrolliert wird und aus einem Teil, der von anderen Web-API's befüllt wird.

Die Deserialisierung erfolgt momentan über selbstgeschriebene Klassen, die von JsonConvert erben, da ich damit große Teile des JSON-Strings nicht verarbeiten muss --> hilft mir auch damit, dass ich Änderungen im Teil, die für die interne Struktur irrelevant sind, nicht übernehmen muss.

Aktuell läuft das auch sehr gut und zeigte sich auch gegenüber Änderungen resilient.

Das Problem ist, dass ich damit im Browser einen großen Teil des Heap belaste. Wenn der JSON-String anwächst (≥10MB) bekomme ich damit ein Problem, dass ich nun über den für Unity zugewiesenen Speicherbereich komme und der Unity-Kontext abstürzt.

Auch habe ich die Komponente, die für die Deserialisierung zuständig ist, in einem eigenen nuget in Unity eingebunden. Dieses Nuget-Paket hat eine Abhängigkeit zu Newtonsoft.Json v. 13.0.1.

Jetzt wollte ich diesen Teil überarbeiten, habe mir für die Json-Struktur eine entsprechende Klassenhierarchie geschrieben und über JsonConvert.DeserializeObject auch de-serialisieren können.
Die Benchmarks haben dafür auch einen deutlichen Vorteil gezeigt:

Method Mean Error StdDev Gen0 Gen1 Allocated
Convert_First 43.47 ms 0.505 ms 0.448 ms 250.0000 83.3333 26.54 MB
Convert_Second 45.25 ms 0.491 ms 0.435 ms - - 5.82 MB

Wobei Convert_First der selbstgeschriebene Ansatz war und Convert_Second über JsonConvert.DeserializeObject.

Allerdings stehe ich jetzt vor dem Problem, dass die letzte Version der API, über die der JSON-String kommt, die Struktur etwas geändert hat (im Teil, der nicht in meiner Kontrolle liegt).
Zwar wäre es für mich möglich, die Klassenhierarchie dementsprechend anzupassen, aber Anpassungen müssten dann immer übernommen werden und ich verliere die Resilienz, die ich aktuell habe.

Die Interfaces, die benutzt werden für den Aufbau des JSON-Strings, sind hierbei in TypeScript geschrieben.

Welchen Ansatz könnte ich nun verfolgen, um einerseits die jetzige Flexibilität beizubehalten, aber gleichzeitig den allokierten Speicher gering zu halten?

Grüße,
Yeats

T
2.219 Beiträge seit 2008
vor einem Jahr

Welche Unterschiede gibt es den zwischen den Api Versionen in der Struktur?
Wenn diese nicht sonderlich groß wären, dann könntest die diese in der gleichen Klasse abdecken.
Falls es z.B. zu Breaking Changes kommt könntest du ggf. mit JToken arbeiten.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

Y
Yeats Themenstarter:in
102 Beiträge seit 2005
vor einem Jahr

Danke für die Antwort T-Virus.

Momentan arbeite ich auch mit JToken, JObject, JArray. Aber damit allokiere ich zu viel Speicher.

Die Struktur unterscheidet sich in einigen Properties/neue Klassen.

Zwar wäre es für mich möglich, die Klassenhierarchie dementsprechend anzupassen, aber Anpassungen müssten dann immer übernommen werden und ich verliere die Resilienz, die ich aktuell habe.

16.806 Beiträge seit 2008
vor einem Jahr

Welchen Ansatz könnte ich nun verfolgen, um einerseits die jetzige Flexibilität beizubehalten, aber gleichzeitig den allokierten Speicher gering zu halten?

In diesem Fall sehe ich das als gegenläufige Wünsche an.
Flexibilität musst Du Dir in diesem Fall leider erkaufen.

PS: System.Text.Json basiert mittlerweile auf Source Code Generators, die nur einen Bruchteil an Performance von Newtonsoft.Json brauchen; aber auch hier mit strikten Strukturen gearbeitet wird, wie es in Json vorgesehen ist.

Aus diesem Grund ist

Dieser JSON-String besteht dabei aus einem Teil, der von mir kontrolliert wird und aus einem Teil, der von anderen Web-API's befüllt wird.

letzteres auch eine Gefahr, weil das letztere (so verstehe ich es) injiziert wird und damit die Stabilität beeinträchtigt.
Im Endeffekt ist das nicht die Grundidee von Schittststellen, die Standards verfolgen.

Normalerweise solltest Du Deine Json vollständig kontrollieren und evtl. einen Mechanismus bauen, der zwar die Fremdaten variabel handhaben kann, aber immer in eine stabile Json überführt. Also quasi ein Converter dazwischen statt Plaintext rein posten.

Y
Yeats Themenstarter:in
102 Beiträge seit 2005
vor einem Jahr

Danke für die Antwort Abt.

Ich hatte eine solche Antwort erwartet. Danke für die Bestätigung!

16.806 Beiträge seit 2008
vor einem Jahr

Nimm das aber als generelle und nicht als spezifische Antwort.
Niemand hier kennt Deinen Code, wie effizient oder ineffizient dieser ist. Nur: Dynamik kostet halt etwas.