AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Erfahrungen mit TJsonSerializer

Ein Thema von Incocnito · begonnen am 7. Aug 2025 · letzter Beitrag vom 8. Aug 2025
Antwort Antwort
Seite 1 von 2  1 2      
Incocnito

Registriert seit: 28. Nov 2016
237 Beiträge
 
#1

Erfahrungen mit TJsonSerializer

  Alt 7. Aug 2025, 10:30
Moin Zusammen,

ich hatte von der KI bei einer Performance-Analyse mal den Tipp bekommen, dass ich statt REST.Json -> TJson.JsonToObject mal System.Json.Serializer -> TJsonSerializer.Create().Deserialize benutzen sollte. Was hatte ich mich gefreut, dass das so viel schneller lief. Hatte bei meiner Freude völlig übersehen, dass einfach gar keine Werte in das Objekt übernommen wurden.

Ich hatte also ein Test-Projekt angelegt und das mal auf ein minimales Beispiel runter gebrochen.

Delphi-Quellcode:
unit main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TTest = class
  private
    FTest : String;
    FTest2 : Integer;
  public
    property Test : String read FTest write FTest;
    property Test2 : Integer read FTest2 write FTest2;
  end;

type
  TfrmMain = class(TForm)
    pnlIn: TPanel;
    spTrenner: TSplitter;
    pnlOut: TPanel;
    lblInput: TLabel;
    memInput: TMemo;
    btnStart: TButton;
    lblOutput: TLabel;
    memOutput: TMemo;
    btnClose: TButton;
    procedure btnCloseClick(Sender: TObject);
    procedure btnStartClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  frmMain: TfrmMain;

implementation

uses
  System.JSON.Serializers,
  Rest.Json;

{$R *.dfm}

procedure TfrmMain.btnCloseClick(Sender: TObject);
begin
  Close();
end;

procedure TfrmMain.btnStartClick(Sender: TObject);
var
  tmp : TTest;
  js : TJsonSerializer;
begin
  // V1:
  {
  tmp := TJson.JsonToObject<TTest>(memInput.Lines.Text);
  try
    memOutput.Lines.Text := TJson.ObjectToJsonString(tmp);
  except
    memOutput.Lines.Text := '';
  end;
  }


  // V2:
  js := TJsonSerializer.Create();
  try
    tmp := js.Deserialize<TTest>(memInput.Lines.Text);
    try
      try
        memOutput.Lines.Text := TJson.ObjectToJsonString(tmp);
      except
        on E: Exception do
          memOutput.Lines.Text := 'Fehler: ' + E.Message;
      end;
    finally
      tmp.Free();
    end;
  finally
    js.Free();
  end;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  memInput.Lines.Text := '{"Test":"Wert1","Test2":12}';
end;

end.
Version 1 mit TJson.JsonToObject funktioniert wunderbar.
Version 2 mit js.Deserialize funktioniert nicht.

Die KI kam darauf mit lustigen Tipps, dass ich statt "public" doch "published" verweden soll,
oder alle Private-Eigenschaften mit "[JsonIn]" als Attribut erweitern sollte,
aber guess what, hat natürlich nicht funktioniert.

Wir verwenden Delphi 11.

Hat da jemand eine Lösung für?

Liebe Grüße
Incocnito
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.494 Beiträge
 
Delphi 12 Athens
 
#2

AW: Erfahrungen mit TJsonSerializer

  Alt 7. Aug 2025, 12:47
Versuch doch mal so:
Delphi-Quellcode:
var
  tmp: TTest;
begin
  tmp := TTest.Create;
  try
    tmp.Test := "Wert2";
    tmp.Test2 := 12;

    memOutput.Lines.Text := TJson.ObjectToJsonString(tmp);
  finally
    tmp.Free;
  end;
end;
Delphi-Quellcode:
var
  tmp: TTest;
begin
  tmp := TJson.JsonToObject<TTest>(memOutput.Lines.Text);
  try
    memOutput.Lines.Clear;
    memOutput.Lines.Add(Format('tmp.Test: %s', [tmp.Test]));
    memOutput.Lines.Add(Format('tmp.Test2: %d', [tmp.Test2]));
  finally
    tmp.Free;
  end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.773 Beiträge
 
Delphi 12 Athens
 
#3

AW: Erfahrungen mit TJsonSerializer

  Alt 7. Aug 2025, 13:21
Wenn du der Klasse TTest das Attribut [JsonSerialize(TJsonMemberSerialization.Public)] voranstellst, sollte es gehen (zumindest in Delphi 12.3). Die Tatsache, dass das nicht ohne geht, zeigt noch erhebliche Mängel in der Implementierung. Vermutlich sollte man das besser noch eine Weile reifen lassen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Incocnito

Registriert seit: 28. Nov 2016
237 Beiträge
 
#4

AW: Erfahrungen mit TJsonSerializer

  Alt 7. Aug 2025, 14:00
Versuch doch mal so:
Delphi-Quellcode:
var
  tmp: TTest;
begin
  tmp := TTest.Create;
  try
    tmp.Test := "Wert2";
    tmp.Test2 := 12;

    memOutput.Lines.Text := TJson.ObjectToJsonString(tmp);
  finally
    tmp.Free;
  end;
end;
Delphi-Quellcode:
var
  tmp: TTest;
begin
  tmp := TJson.JsonToObject<TTest>(memOutput.Lines.Text);
  try
    memOutput.Lines.Clear;
    memOutput.Lines.Add(Format('tmp.Test: %s', [tmp.Test]));
    memOutput.Lines.Add(Format('tmp.Test2: %d', [tmp.Test2]));
  finally
    tmp.Free;
  end;
end;
Ja, "TJson.ObjectToJsonString" und "TJson.JsonToObject" funktionieren ja wie gesagt (vgl. Version 1, was auskommentiert ist).
Es geht ja darum zu schauen, ob TJsonSerializer nicht sinnvoll zum Laufen gebracht werden kann.

---

Wenn du der Klasse TTest das Attribut [JsonSerialize(TJsonMemberSerialization.Public)] voranstellst, sollte es gehen (zumindest in Delphi 12.3). Die Tatsache, dass das nicht ohne geht, zeigt noch erhebliche Mängel in der Implementierung. Vermutlich sollte man das besser noch eine Weile reifen lassen.
Dann würden nur die Public-Werte übernommen werden.
Delphi-Quellcode:
  TTest4711 = class
  private
    FTest : String;
    FTest2 : Integer;
    FTest3 : Boolean;
  public
    constructor Create(const bTest3: Boolean); // FTest3 := bTest3;
    function GetTest3() : Boolean; // Result := FTest3;
    property Test : String read FTest write FTest;
    property Test2 : Integer read FTest2 write FTest2;
  end;
<- das würde dann nicht gehen. Bzw. er übernimmt die Private-Eigenschaft FTest3 nicht.

Liebe Grüße
Incocnito
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.773 Beiträge
 
Delphi 12 Athens
 
#5

AW: Erfahrungen mit TJsonSerializer

  Alt 7. Aug 2025, 15:11
Ja, TJsonMemberSerialization.Fields ist der Default, aber das hat Probleme beim Deserialize. Während beim Serialize das F bei den Feldnamen entfernt wird, fehlt dies offenbar beim Vergleich der Feldnamen während des Deserialize in TJsonObjectContract.GetClosestMatchProperty . Ich habe das jetzt nicht bis zu Ende analysiert, aber ich gehe da von einem Bug aus. Es wundert mich aber, dass das offenbar noch keinem aufgefallen ist.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
fisipjm

Registriert seit: 28. Okt 2013
350 Beiträge
 
Delphi 12 Athens
 
#6

AW: Erfahrungen mit TJsonSerializer

  Alt 7. Aug 2025, 15:23
Wenn es dir um Performance geht, kann ich dir das hier empfehlen:
https://github.com/paolo-rossi/delphi-neon
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.214 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Erfahrungen mit TJsonSerializer

  Alt 7. Aug 2025, 16:41
Ich habe Neon bislang auch nur oberflächlich und für kleinere Dinge verwendet, war aber insgesamt überrascht wie gut das funktioniert hat, und man es notfalls auch anpassen/erweitern kann.
  Mit Zitat antworten Zitat
Rolf Frei

Registriert seit: 19. Jun 2006
657 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Erfahrungen mit TJsonSerializer

  Alt 7. Aug 2025, 16:43
Ja kann dir Neon auch nur empfehlen. Ich nutze das selber seit einiger Zeit und bin davon sehr begeistert.
  Mit Zitat antworten Zitat
Incocnito

Registriert seit: 28. Nov 2016
237 Beiträge
 
#9

AW: Erfahrungen mit TJsonSerializer

  Alt 7. Aug 2025, 16:50
Ja, TJsonMemberSerialization.Fields ist der Default, aber das hat Probleme beim Deserialize. Während beim Serialize das F bei den Feldnamen entfernt wird, fehlt dies offenbar beim Vergleich der Feldnamen während des Deserialize in TJsonObjectContract.GetClosestMatchProperty . Ich habe das jetzt nicht bis zu Ende analysiert, aber ich gehe da von einem Bug aus. Es wundert mich aber, dass das offenbar noch keinem aufgefallen ist.
Ja, meine Analyse wird allmählich etwas umfangreicher (verschiedene Konstellationen, neuer Parameter "FTest3", der nur Private ist. Interfaces, umfangreichere Logs samt Performance-Tests. Mit [JsonName('Test')] als Attribut pro Feld geht es (was ja auch deiner "Das 'F' wird nicht entfernt"-Erkenntnis entsprechen würde). Ich halte euch da hier auf dem Laufenden.

Wenn es dir um Performance geht, kann ich dir das hier empfehlen:
https://github.com/paolo-rossi/delphi-neon
Ja es gibt etliche Drittanbieter-Lösungen. Darauf möchte ich aber in diesem Fall verzichten.
Der minimale Performance-Gewinn ist es mir nicht wert mich da ggf. abhängig zu machen. Ggf. regelmäßige Updates einzupflegen. Oder gar Gefahr zu laufen, dass das Projekt eingestampft wird und alles nochmal umbauen zu müssen.

Liebe Grüße und schonmal vielen Dank bis hierhin für eure Mühe
Incocnito
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.773 Beiträge
 
Delphi 12 Athens
 
#10

AW: Erfahrungen mit TJsonSerializer

  Alt 7. Aug 2025, 17:15
Man muss auch anerkennen, dass das Delphi-eigene TJson mit jeder Version besser wird. Wenn man also rein auf Bordmittel vertrauen will, liegt man damit auch nicht völlig daneben.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:48 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz