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.