Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Json -> Unity3D
Yeats
myCSharp.de - Member



Dabei seit:
Beiträge: 100
Herkunft: Österreich

Themenstarter:

Json -> Unity3D

beantworten | zitieren | melden

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
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 2.028
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers
Yeats
myCSharp.de - Member



Dabei seit:
Beiträge: 100
Herkunft: Österreich

Themenstarter:

beantworten | zitieren | melden

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.
Zitat
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.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16.026

beantworten | zitieren | melden

Zitat von Yeats
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
Zitat
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.
private Nachricht | Beiträge des Benutzers
Yeats
myCSharp.de - Member



Dabei seit:
Beiträge: 100
Herkunft: Österreich

Themenstarter:

beantworten | zitieren | melden

Danke für die Antwort Abt.

Ich hatte eine solche Antwort erwartet. Danke für die Bestätigung!
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16.026

beantworten | zitieren | melden

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.
private Nachricht | Beiträge des Benutzers