|
![]() |
Registriert seit: 28. Nov 2016 237 Beiträge |
#11
Wer das einmal selbst nachstellen möchte, hier einmal der Code meiner Test-Unit:
Delphi-Quellcode:
Am Ende hatte ich dann die Version mit dem Resolver als eigene Klasse / Unit SimpleJsonSerializer noch eingebaut und hier getestet.
unit JsonSerializerAnalyse;
interface uses System.SysUtils, System.Classes, System.JSON.Serializers, System.JSON.Types, Rest.Json, System.Diagnostics, System.TimeSpan, System.JSON.Readers, System.JSON.Writers, System.Rtti, System.TypInfo; // Externe Aufruf-Prozedur procedure RunAllTests(); //Procedure FinalTest(var Results: TStringList); type // Gemeinsames Interface für alle Test-Klassen ITestJsonClass = interface ['{E62D3704-A6B9-4B05-94A4-553C6FD818AA}'] function GetTest() : String; function GetTest2() : Integer; function GetTest3() : Boolean; function GetInfoText() : String; end; // Test B: Custom Boolean Converter TCustomBooleanConverter = class(TJsonConverter) public function CanConvert(ATypeInf: PTypeInfo) : Boolean; override; function ReadJson(const AReader: TJsonReader; ATypeInf: PTypeInfo; const AExistingValue: TValue; const ASerializer: TJsonSerializer) : TValue; override; procedure WriteJson(const AWriter: TJsonWriter; const AValue: TValue; const ASerializer: TJsonSerializer); override; end; // Test C: Smart Contract Resolver - behandelt F-Prefix automatisch TDelphiFieldContractResolver = class(TJsonDefaultContractResolver) protected function ResolvePropertyName(const AName: string): string; override; public constructor Create(); overload; constructor Create(AMemberSerialization: TJsonMemberSerialization); overload; end; // Test 1: Original Klasse TTest = class(TInterfacedObject, ITestJsonClass) private FTest : String; FTest2 : Integer; FTest3 : Boolean; public constructor Create(); overload; constructor Create(const bTest3: Boolean); overload; function GetTest() : String; function GetTest2() : Integer; function GetTest3() : Boolean; function GetInfoText() : String; property Test : String read GetTest write FTest; property Test2 : Integer read GetTest2 write FTest2; end; // Test 2: Mit JsonSerialize(Public) Attribut [JsonSerialize(TJsonMemberSerialization.Public)] TTestWithAttribute = class(TInterfacedObject, ITestJsonClass) private FTest : String; FTest2 : Integer; FTest3 : Boolean; public constructor Create(); overload; constructor Create(const bTest3: Boolean); overload; function GetTest() : String; function GetTest2() : Integer; function GetTest3() : Boolean; function GetInfoText() : String; property Test : String read GetTest write FTest; property Test2 : Integer read GetTest2 write FTest2; end; // Test 3: Mit JsonSerialize(Fields) Attribut [JsonSerialize(TJsonMemberSerialization.Fields)] TTestWithFields = class(TInterfacedObject, ITestJsonClass) private FTest : String; FTest2 : Integer; FTest3 : Boolean; public constructor Create(); overload; constructor Create(const bTest3: Boolean); overload; function GetTest() : String; function GetTest2() : Integer; function GetTest3() : Boolean; function GetInfoText() : String; property Test : String read GetTest write FTest; property Test2 : Integer read GetTest2 write FTest2; end; // Test 4: Mit JsonIn auf Fields TTestWithJsonIn = class(TInterfacedObject, ITestJsonClass) private [JsonIn] FTest : String; [JsonIn] FTest2 : Integer; [JsonIn] FTest3 : Boolean; public constructor Create(); overload; constructor Create(const bTest3: Boolean); overload; function GetTest() : String; function GetTest2() : Integer; function GetTest3() : Boolean; function GetInfoText() : String; property Test : String read GetTest write FTest; property Test2 : Integer read GetTest2 write FTest2; end; // Test 5: Mit JsonIn auf Properties TTestWithJsonInProps = class(TInterfacedObject, ITestJsonClass) private FTest : String; FTest2 : Integer; FTest3 : Boolean; public constructor Create(); overload; constructor Create(const bTest3: Boolean); overload; function GetTest() : String; function GetTest2() : Integer; function GetTest3() : Boolean; function GetInfoText() : String; [JsonIn] property Test : String read GetTest write FTest; [JsonIn] property Test2 : Integer read GetTest2 write FTest2; end; // Test 6: Mit NUR JsonName auf Fields TTestWithOnlyJsonName = class(TInterfacedObject, ITestJsonClass) private [JsonName('Test')] FTest : String; [JsonName('Test2')] FTest2 : Integer; [JsonName('Test3')] FTest3 : Boolean; public constructor Create(); overload; constructor Create(const bTest3: Boolean); overload; function GetTest() : String; function GetTest2() : Integer; function GetTest3() : Boolean; function GetInfoText() : String; property Test : String read GetTest write FTest; property Test2 : Integer read GetTest2 write FTest2; end; // Test 7: Mit JsonIn + JsonName auf Fields TTestWithJsonNamedFields = class(TInterfacedObject, ITestJsonClass) private [JsonIn, JsonName('Test')] FTest : String; [JsonIn, JsonName('Test2')] FTest2 : Integer; [JsonIn, JsonName('Test3')] FTest3 : Boolean; public constructor Create(); overload; constructor Create(const bTest3: Boolean); overload; function GetTest() : String; function GetTest2() : Integer; function GetTest3() : Boolean; function GetInfoText() : String; property Test : String read GetTest write FTest; property Test2 : Integer read GetTest2 write FTest2; end; // Test 8: Mit TJsonMemberSerialization.In und JsonIn überall [JsonSerialize(TJsonMemberSerialization.In)] TTestWithSerializeIn = class(TInterfacedObject, ITestJsonClass) private [JsonIn] FTest : String; [JsonIn] FTest2 : Integer; [JsonIn] FTest3 : Boolean; public constructor Create(); overload; constructor Create(const bTest3: Boolean); overload; function GetTest() : String; function GetTest2() : Integer; function GetTest3() : Boolean; function GetInfoText() : String; [JsonIn] property Test : String read GetTest write FTest; [JsonIn] property Test2 : Integer read GetTest2 write FTest2; end; // Test 9: Mit JsonIgnore auf Properties, nur Fields TTestWithIgnoredProps = class(TInterfacedObject, ITestJsonClass) private [JsonIn] FTest : String; [JsonIn] FTest2 : Integer; [JsonIn] FTest3 : Boolean; public constructor Create(); overload; constructor Create(const bTest3: Boolean); overload; function GetTest() : String; function GetTest2() : Integer; function GetTest3() : Boolean; function GetInfoText() : String; [JsonIgnore] property Test : String read GetTest write FTest; [JsonIgnore] property Test2 : Integer read GetTest2 write FTest2; end; // Test 10: Custom Boolean Converter auf Field-Ebene [JsonSerialize(TJsonMemberSerialization.Fields)] TTestWithCustomConverter = class(TInterfacedObject, ITestJsonClass) private FTest : String; FTest2 : Integer; [JsonConverter(TCustomBooleanConverter)] FTest3 : Boolean; public constructor Create(); overload; constructor Create(const bTest3: Boolean); overload; function GetTest() : String; function GetTest2() : Integer; function GetTest3() : Boolean; function GetInfoText() : String; property Test : String read GetTest write FTest; property Test2 : Integer read GetTest2 write FTest2; end; // Test 11: NICHT-KONFORME Feldnamen ohne führendes "F" für JSON-Mapping-Test // WARNUNG: Diese Klasse verwendet BEWUSST nicht-konforme Feldnamen! // Normalerweise sollten private Felder mit "F" beginnen (z.B. FTest) // Hier wird das "F" weggelassen um zu testen, ob TJsonSerializer // die JSON-Property-Namen direkt mit Feldnamen matchen kann TTestWithNonConformFieldNames = class(TInterfacedObject, ITestJsonClass) private Test : String; // NICHT-KONFORM: Sollte normalerweise "FTest" heißen Test2 : Integer; // NICHT-KONFORM: Sollte normalerweise "FTest2" heißen Test3 : Boolean; // NICHT-KONFORM: Sollte normalerweise "FTest3" heißen public constructor Create(); overload; constructor Create(const bTest3: Boolean); overload; function GetTest() : String; function GetTest2() : Integer; function GetTest3() : Boolean; function GetInfoText() : String; // Properties mit Unterstrich da Feldnamen bereits "Test", "Test2", "Test3" sind property Test_ : String read Test write Test; property Test2_ : Integer read Test2 write Test2; end; // Test Alt 1: Mit RTTI-Direktive für private Fields (AUSKOMMENTIERT) (* {$RTTI EXPLICIT FIELDS([vcPrivate, vcProtected, vcPublic, vcPublished])} [JsonSerialize(TJsonMemberSerialization.Fields)] TTestWithRTTIFields = class private FTest : String; FTest2 : Integer; FTest3 : Boolean; public constructor Create(const bTest3: Boolean); function GetTest3() : Boolean; property Test : String read FTest write FTest; property Test2 : Integer read FTest2 write FTest2; end; {$RTTI EXPLICIT FIELDS(DefaultFieldRttiVisibility)} *) // Test Alt 2: Mit $M+ und JsonSerialize Fields (AUSKOMMENTIERT) (* {$M+} [JsonSerialize(TJsonMemberSerialization.Fields)] TTestWithTypeInfo = class private FTest : String; FTest2 : Integer; FTest3 : Boolean; public constructor Create(const bTest3: Boolean); function GetTest3() : Boolean; property Test : String read FTest write FTest; property Test2 : Integer read FTest2 write FTest2; end; {$M-} *) // Performance Test Wrapper TJsonPerformanceTest = class private FJsonString : string; FIterations : Integer; public constructor Create(); procedure TestRESTJson(var Results: TStringList); procedure TestTJsonSerializerMain<T: class, constructor>(var Results: TStringList); procedure TestTJsonSerializerWithResolverMain<T: class, constructor>(var Results: TStringList); procedure TestTJsonSerializerWithSmartResolverMain<T: class, constructor>(var Results: TStringList); end; implementation uses //SimpleJsonSerializer, System.JSON.Converters; { TTest } constructor TTest.Create(); begin inherited Create(); FTest3 := False; end; constructor TTest.Create(const bTest3: Boolean); begin inherited Create(); FTest3 := bTest3; end; function TTest.GetTest() : String; begin Result := FTest; end; function TTest.GetTest2() : Integer; begin Result := FTest2; end; function TTest.GetTest3() : Boolean; begin Result := FTest3; end; function TTest.GetInfoText() : String; begin Result := 'TJsonSerializer Original'; end; { TTestWithAttribute } constructor TTestWithAttribute.Create(); begin inherited Create(); FTest3 := False; end; constructor TTestWithAttribute.Create(const bTest3: Boolean); begin inherited Create(); FTest3 := bTest3; end; function TTestWithAttribute.GetTest() : String; begin Result := FTest; end; function TTestWithAttribute.GetTest2() : Integer; begin Result := FTest2; end; function TTestWithAttribute.GetTest3() : Boolean; begin Result := FTest3; end; function TTestWithAttribute.GetInfoText() : String; begin Result := 'TJsonSerializer mit JsonSerialize(Public) Attribut'; end; { TTestWithFields } constructor TTestWithFields.Create(); begin inherited Create(); FTest3 := False; end; constructor TTestWithFields.Create(const bTest3: Boolean); begin inherited Create(); FTest3 := bTest3; end; function TTestWithFields.GetTest() : String; begin Result := FTest; end; function TTestWithFields.GetTest2() : Integer; begin Result := FTest2; end; function TTestWithFields.GetTest3() : Boolean; begin Result := FTest3; end; function TTestWithFields.GetInfoText() : String; begin Result := 'TJsonSerializer mit JsonSerialize(Fields) Attribut'; end; { TTestWithJsonIn } constructor TTestWithJsonIn.Create(); begin inherited Create(); FTest3 := False; end; constructor TTestWithJsonIn.Create(const bTest3: Boolean); begin inherited Create(); FTest3 := bTest3; end; function TTestWithJsonIn.GetTest() : String; begin Result := FTest; end; function TTestWithJsonIn.GetTest2() : Integer; begin Result := FTest2; end; function TTestWithJsonIn.GetTest3() : Boolean; begin Result := FTest3; end; function TTestWithJsonIn.GetInfoText() : String; begin Result := 'TJsonSerializer mit JsonIn auf Fields'; end; { TTestWithJsonInProps } constructor TTestWithJsonInProps.Create(); begin inherited Create(); FTest3 := False; end; constructor TTestWithJsonInProps.Create(const bTest3: Boolean); begin inherited Create(); FTest3 := bTest3; end; function TTestWithJsonInProps.GetTest() : String; begin Result := FTest; end; function TTestWithJsonInProps.GetTest2() : Integer; begin Result := FTest2; end; function TTestWithJsonInProps.GetTest3() : Boolean; begin Result := FTest3; end; function TTestWithJsonInProps.GetInfoText() : String; begin Result := 'TJsonSerializer mit JsonIn auf Properties'; end; { TTestWithOnlyJsonName } constructor TTestWithOnlyJsonName.Create(); begin inherited Create(); FTest3 := False; end; constructor TTestWithOnlyJsonName.Create(const bTest3: Boolean); begin inherited Create(); FTest3 := bTest3; end; function TTestWithOnlyJsonName.GetTest() : String; begin Result := FTest; end; function TTestWithOnlyJsonName.GetTest2() : Integer; begin Result := FTest2; end; function TTestWithOnlyJsonName.GetTest3() : Boolean; begin Result := FTest3; end; function TTestWithOnlyJsonName.GetInfoText() : String; begin Result := 'TJsonSerializer mit nur JsonName auf Fields'; end; { TTestWithJsonNamedFields } constructor TTestWithJsonNamedFields.Create(); begin inherited Create(); FTest3 := False; end; constructor TTestWithJsonNamedFields.Create(const bTest3: Boolean); begin inherited Create(); FTest3 := bTest3; end; function TTestWithJsonNamedFields.GetTest() : String; begin Result := FTest; end; function TTestWithJsonNamedFields.GetTest2() : Integer; begin Result := FTest2; end; function TTestWithJsonNamedFields.GetTest3() : Boolean; begin Result := FTest3; end; function TTestWithJsonNamedFields.GetInfoText() : String; begin Result := 'TJsonSerializer mit JsonIn+JsonName auf Fields'; end; { TTestWithSerializeIn } constructor TTestWithSerializeIn.Create(); begin inherited Create(); FTest3 := False; end; constructor TTestWithSerializeIn.Create(const bTest3: Boolean); begin inherited Create(); FTest3 := bTest3; end; function TTestWithSerializeIn.GetTest() : String; begin Result := FTest; end; function TTestWithSerializeIn.GetTest2() : Integer; begin Result := FTest2; end; function TTestWithSerializeIn.GetTest3() : Boolean; begin Result := FTest3; end; function TTestWithSerializeIn.GetInfoText() : String; begin Result := 'TJsonSerializer mit Serialize In'; end; { TTestWithIgnoredProps } constructor TTestWithIgnoredProps.Create(); begin inherited Create(); FTest3 := False; end; constructor TTestWithIgnoredProps.Create(const bTest3: Boolean); begin inherited Create(); FTest3 := bTest3; end; function TTestWithIgnoredProps.GetTest() : String; begin Result := FTest; end; function TTestWithIgnoredProps.GetTest2() : Integer; begin Result := FTest2; end; function TTestWithIgnoredProps.GetTest3() : Boolean; begin Result := FTest3; end; function TTestWithIgnoredProps.GetInfoText() : String; begin Result := 'TJsonSerializer mit JsonIgnore Properties'; end; { TTestWithCustomConverter } constructor TTestWithCustomConverter.Create(); begin inherited Create(); FTest3 := False; end; constructor TTestWithCustomConverter.Create(const bTest3: Boolean); begin inherited Create(); FTest3 := bTest3; end; function TTestWithCustomConverter.GetTest() : String; begin Result := FTest; end; function TTestWithCustomConverter.GetTest2() : Integer; begin Result := FTest2; end; function TTestWithCustomConverter.GetTest3() : Boolean; begin Result := FTest3; end; function TTestWithCustomConverter.GetInfoText() : String; begin Result := 'TJsonSerializer mit Custom Boolean Converter'; end; { TTestWithNonConformFieldNames } constructor TTestWithNonConformFieldNames.Create(); begin inherited Create(); Test3 := False; end; constructor TTestWithNonConformFieldNames.Create(const bTest3: Boolean); begin inherited Create(); Test3 := bTest3; end; function TTestWithNonConformFieldNames.GetTest() : String; begin Result := Test; end; function TTestWithNonConformFieldNames.GetTest2() : Integer; begin Result := Test2; end; function TTestWithNonConformFieldNames.GetTest3() : Boolean; begin Result := Test3; end; function TTestWithNonConformFieldNames.GetInfoText() : String; begin Result := 'TJsonSerializer mit nicht-konformen Feldnamen (ohne F-Prefix)'; end; { Alternative Test Implementierungen - AUSKOMMENTIERT } { TTestWithRTTIFields - Test Alt 1 } (* constructor TTestWithRTTIFields.Create(const bTest3: Boolean); begin inherited Create(); FTest3 := bTest3; end; function TTestWithRTTIFields.GetTest3() : Boolean; begin Result := FTest3; end; *) { TTestWithTypeInfo - Test Alt 2 } (* constructor TTestWithTypeInfo.Create(const bTest3: Boolean); begin inherited Create(); FTest3 := bTest3; end; function TTestWithTypeInfo.GetTest3() : Boolean; begin Result := FTest3; end; *) { TCustomBooleanConverter } function TCustomBooleanConverter.CanConvert(ATypeInf: PTypeInfo) : Boolean; begin Result := ATypeInf = TypeInfo(Boolean); end; function TCustomBooleanConverter.ReadJson(const AReader: TJsonReader; ATypeInf: PTypeInfo; const AExistingValue: TValue; const ASerializer: TJsonSerializer) : TValue; begin if AReader.TokenType = TJsonToken.Boolean then Result := TValue.From<Boolean>(AReader.Value.AsBoolean) else if AReader.TokenType = TJsonToken.String then Result := TValue.From<Boolean>(SameText(AReader.Value.AsString, 'true')) else Result := TValue.From<Boolean>(False); end; procedure TCustomBooleanConverter.WriteJson(const AWriter: TJsonWriter; const AValue: TValue; const ASerializer: TJsonSerializer); begin AWriter.WriteValue(AValue.AsBoolean); end; { TDelphiFieldContractResolver } constructor TDelphiFieldContractResolver.Create(); begin inherited Create(TJsonMemberSerialization.Fields); end; constructor TDelphiFieldContractResolver.Create(AMemberSerialization: TJsonMemberSerialization); begin inherited Create(AMemberSerialization); end; function TDelphiFieldContractResolver.ResolvePropertyName(const AName: string): string; begin // Entferne "F" Prefix von private Fields für JSON-Mapping // FTest ? Test, FUserName ? UserName, etc. if (Length(AName) > 1) and (AName[1] = 'F') and CharInSet(AName[2], ['A'..'Z']) then Result := Copy(AName, 2, Length(AName) - 1) else Result := AName; end; { TJsonPerformanceTest } constructor TJsonPerformanceTest.Create(); begin FJsonString := '{"Test":"Wert1","Test2":12,"Test3":true}'; FIterations := 10000; // 10k Iterationen für Performance-Test end; procedure TJsonPerformanceTest.TestRESTJson(var Results: TStringList); var sw : TStopwatch; tmp : TTest; tmp2 : TTest; i : Integer; timeSpan : TTimeSpan; begin tmp2 := TTest.Create(); try Results.Add('=== REST.Json ' + tmp2.GetInfoText() + ' ==='); sw := TStopwatch.StartNew(); for i := 1 to FIterations do begin tmp := TJson.JsonToObject<TTest>(FJsonString); try // Verifikation if (i = 1) then begin Results.Add('Deserialisiert - Test: "' + tmp.Test + '", Test2: ' + IntToStr(tmp.Test2) + ', Test3: ' + BoolToStr(tmp.GetTest3(), True)); Results.Add('Rueck-Serialisiert - Test: "' + TJson.ObjectToJsonString(tmp) + '"'); end; finally tmp.Free(); end; end; sw.Stop(); timeSpan := sw.Elapsed; Results.Add('REST.Json ' + tmp2.GetInfoText() + ' Zeit: ' + FormatFloat('0.000', timeSpan.TotalMilliseconds) + ' ms'); Results.Add(''); finally tmp2.Free(); end; end; procedure TJsonPerformanceTest.TestTJsonSerializerMain<T>(var Results: TStringList); var sw : TStopwatch; deserializedObj : T; deserializedIntf : ITestJsonClass; baseInfoClass : T; intfInfoClass : ITestJsonClass; sInfoText : String; js : TJsonSerializer; i : Integer; timeSpan : TTimeSpan; begin baseInfoClass := T.Create(); try if (Supports(baseInfoClass, ITestJsonClass, intfInfoClass)) then begin sInfoText := intfInfoClass.GetInfoText(); end else begin sInfoText := '<Error Class-Cast>'; end; Results.Add('=== Test 1 (Generic): ' + sInfoText + ' ==='); sw := TStopwatch.StartNew(); for i := 1 to FIterations do begin js := TJsonSerializer.Create(); try deserializedObj := js.Deserialize<T>(FJsonString); try if (Supports(deserializedObj, ITestJsonClass, deserializedIntf)) then begin // Verifikation if (i = 1) then begin Results.Add( 'Deserialisiert - Test: "' + deserializedIntf.GetTest() + '", ' + 'Test2: ' + IntToStr(deserializedIntf.GetTest2()) + ', ' + 'Test3: ' + BoolToStr(deserializedIntf.GetTest3(), True) ); Results.Add('Rueck-Serialisiert - Test: "' + js.Serialize<T>(deserializedObj) + '"'); end; end; finally //deserializedObj.Free(); end; finally js.Free(); end; end; sw.Stop(); timeSpan := sw.Elapsed; Results.Add(sInfoText + ' Zeit: ' + FormatFloat('0.000', timeSpan.TotalMilliseconds) + ' ms'); Results.Add(''); finally //baseInfoClass.Free(); end; end; procedure TJsonPerformanceTest.TestTJsonSerializerWithResolverMain<T>( var Results: TStringList); var sw : TStopwatch; js : TJsonSerializer; contractResolver : TJsonDefaultContractResolver; i : Integer; timeSpan : TTimeSpan; deserializedObj : T; deserializedIntf : ITestJsonClass; baseInfoClass : T; intfInfoClass : ITestJsonClass; sInfoText : String; begin baseInfoClass := T.Create(); try if (Supports(baseInfoClass, ITestJsonClass, intfInfoClass)) then begin sInfoText := intfInfoClass.GetInfoText(); end else begin sInfoText := '<Error Class-Cast>'; end; Results.Add('=== Test 2 (Generic): ' + sInfoText + ' ==='); sw := TStopwatch.StartNew(); for i := 1 to FIterations do begin js := TJsonSerializer.Create(); try contractResolver := TJsonDefaultContractResolver.Create(TJsonMemberSerialization.Public); js.ContractResolver := contractResolver; deserializedObj := js.Deserialize<T>(FJsonString); try if (Supports(deserializedObj, ITestJsonClass, deserializedIntf)) then begin // Verifikation if (i = 1) then begin Results.Add( 'Deserialisiert - Test: "' + deserializedIntf.GetTest() + '", ' + 'Test2: ' + IntToStr(deserializedIntf.GetTest2()) + ', ' + 'Test3: ' + BoolToStr(deserializedIntf.GetTest3(), True) ); Results.Add('Rueck-Serialisiert - Test: "' + js.Serialize<T>(deserializedObj) + '"'); end; end; finally //deserializedObj.Free(); end; finally js.Free(); end; end; sw.Stop(); timeSpan := sw.Elapsed; Results.Add(sInfoText + ' Zeit: ' + FormatFloat('0.000', timeSpan.TotalMilliseconds) + ' ms'); Results.Add(''); finally //baseInfoClass.Free(); end; end; procedure TJsonPerformanceTest.TestTJsonSerializerWithSmartResolverMain<T>( var Results: TStringList); var sw : TStopwatch; js : TJsonSerializer; smartResolver : TDelphiFieldContractResolver; i : Integer; timeSpan : TTimeSpan; deserializedObj : T; deserializedIntf : ITestJsonClass; baseInfoClass : T; intfInfoClass : ITestJsonClass; sInfoText : String; begin baseInfoClass := T.Create(); try if (Supports(baseInfoClass, ITestJsonClass, intfInfoClass)) then begin sInfoText := intfInfoClass.GetInfoText(); end else begin sInfoText := '<Error Class-Cast>'; end; Results.Add('=== Test 3 (Smart Resolver): ' + sInfoText + ' ==='); sw := TStopwatch.StartNew(); for i := 1 to FIterations do begin js := TJsonSerializer.Create(); try smartResolver := TDelphiFieldContractResolver.Create(TJsonMemberSerialization.Fields); js.ContractResolver := smartResolver; deserializedObj := js.Deserialize<T>(FJsonString); try if (Supports(deserializedObj, ITestJsonClass, deserializedIntf)) then begin // Verifikation if (i = 1) then begin Results.Add( 'Deserialisiert - Test: "' + deserializedIntf.GetTest() + '", ' + 'Test2: ' + IntToStr(deserializedIntf.GetTest2()) + ', ' + 'Test3: ' + BoolToStr(deserializedIntf.GetTest3(), True) ); Results.Add('Rueck-Serialisiert - Test: "' + js.Serialize<T>(deserializedObj) + '"'); end; end; finally //deserializedObj.Free(); end; finally js.Free(); end; end; sw.Stop(); timeSpan := sw.Elapsed; Results.Add(sInfoText + ' Zeit: ' + FormatFloat('0.000', timeSpan.TotalMilliseconds) + ' ms'); Results.Add(''); finally //baseInfoClass.Free(); end; end; // Haupttest-Procedure procedure RunAllTests(); var Test : TJsonPerformanceTest; Results : TStringList; begin Test := TJsonPerformanceTest.Create(); Results := TStringList.Create(); try Results.Add('JSON Serialization Performance Test - GEORDNET'); Results.Add('====================================================='); Results.Add('Test JSON: {"Test":"Wert1","Test2":12,"Test3":true}'); Results.Add('Iterationen: 10.000'); Results.Add(''); Results.Add('REFERENZ:'); Results.Add(''); Test.TestRESTJson(Results); Results.Add('TESTS IN REIHENFOLGE:'); Results.Add(''); Test.TestTJsonSerializerMain<TTest>(Results); Test.TestTJsonSerializerMain<TTestWithAttribute>(Results); Test.TestTJsonSerializerMain<TTestWithFields>(Results); Test.TestTJsonSerializerMain<TTestWithJsonIn>(Results); Test.TestTJsonSerializerMain<TTestWithJsonInProps>(Results); Test.TestTJsonSerializerMain<TTestWithOnlyJsonName>(Results); Test.TestTJsonSerializerMain<TTestWithJsonNamedFields>(Results); Test.TestTJsonSerializerMain<TTestWithSerializeIn>(Results); Test.TestTJsonSerializerMain<TTestWithIgnoredProps>(Results); Test.TestTJsonSerializerMain<TTestWithCustomConverter>(Results); Test.TestTJsonSerializerMain<TTestWithNonConformFieldNames>(Results); Test.TestTJsonSerializerWithResolverMain<TTest>(Results); Test.TestTJsonSerializerWithResolverMain<TTestWithAttribute>(Results); Test.TestTJsonSerializerWithResolverMain<TTestWithFields>(Results); Test.TestTJsonSerializerWithResolverMain<TTestWithJsonIn>(Results); Test.TestTJsonSerializerWithResolverMain<TTestWithJsonInProps>(Results); Test.TestTJsonSerializerWithResolverMain<TTestWithOnlyJsonName>(Results); Test.TestTJsonSerializerWithResolverMain<TTestWithJsonNamedFields>(Results); Test.TestTJsonSerializerWithResolverMain<TTestWithSerializeIn>(Results); Test.TestTJsonSerializerWithResolverMain<TTestWithIgnoredProps>(Results); Test.TestTJsonSerializerWithResolverMain<TTestWithCustomConverter>(Results); Test.TestTJsonSerializerWithResolverMain<TTestWithNonConformFieldNames>(Results); Test.TestTJsonSerializerWithSmartResolverMain<TTest>(Results); Test.TestTJsonSerializerWithSmartResolverMain<TTestWithAttribute>(Results); Test.TestTJsonSerializerWithSmartResolverMain<TTestWithFields>(Results); Test.TestTJsonSerializerWithSmartResolverMain<TTestWithJsonIn>(Results); Test.TestTJsonSerializerWithSmartResolverMain<TTestWithJsonInProps>(Results); Test.TestTJsonSerializerWithSmartResolverMain<TTestWithOnlyJsonName>(Results); Test.TestTJsonSerializerWithSmartResolverMain<TTestWithJsonNamedFields>(Results); Test.TestTJsonSerializerWithSmartResolverMain<TTestWithSerializeIn>(Results); Test.TestTJsonSerializerWithSmartResolverMain<TTestWithIgnoredProps>(Results); Test.TestTJsonSerializerWithSmartResolverMain<TTestWithCustomConverter>(Results); Test.TestTJsonSerializerWithSmartResolverMain<TTestWithNonConformFieldNames>(Results); //Test.TestTJsonSerializerMain<TTestWithRTTIFields>(Results); //Test.TestTJsonSerializerMain<TTestWithTypeInfo>(Results); //FinalTest(Results); // Ergebnisse ausgeben Results.SaveToFile('JsonPerformanceTestGeordnet.txt'); finally Results.Free(); Test.Free(); end; end; (* Procedure FinalTest(var Results : TStringList); var js : TFastJsonSerializer; test : TTest; sRef : String; const TESTTEXT = '{"Test":"Wert1","Test2":12,"Test3":true}'; begin js := TFastJsonSerializer.Create(); try test := js.Deserialize<TTest>(TESTTEXT); sRef := js.Serialize<TTest>(test); Results.Add('Neuer Text: ' + sRef); finally js.Free(); end; end; *) end. Das ist für das Nachvollziehen aber irrelevant. Jetzt wäre die Frage, ob das von Embarcadero so gewollt ist. Sinnvoll wäre das meiner Meinung nach aber nicht. |
![]() |
Registriert seit: 20. Jan 2006 Ort: Lübbecke 11.773 Beiträge Delphi 12 Athens |
#12
Nur so als Hinweis: Code der - und insbesondere ganze Units die - nicht auf eine Bildschirmseite passen, sollten besser als Anhang beigelegt werden.
|
![]() |
Registriert seit: 28. Okt 2013 350 Beiträge Delphi 12 Athens |
#13
Wenn es dir um Performance geht, kann ich dir das hier empfehlen:
![]() 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. Incocnito Die Zum teil 10 fache Geschwindigkeit würde ich jetzt nicht unbedingt als "minimal" bezeichnen. Alles von dir angesprochene lässt sich super über die mitzugebende Konfiguration einstellen. |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |