How optimize new RTTI (in XE4) ??? it's very slow !
How optimize new RTTI (in XE4) ??? it's very slow !
when I use the old rtti method (in TypInfo, Set/GetxxxProp family...) it's 5/6 times faster ! mostly is the TValue. Why ?
I writed a function in a class to scan all published properties (with rtti) and compute CRC 32bits on it ; my version with old rtti is 8 times faster than the new rtti ! unbelievable !!!
Unfortunately , for this example, I don't have the new rrti version (because too slow). but the old rtti (and the faster) is:
function ComputeValueCRC(AOldCRC:Cardinal; const AObj:TObject; AProp:PPropInfo):Cardinal;inline;
var
s:string;
ws:WideString;
i:Integer;
i64:int64;
f:Extended;
begin
case AProp^.PropType^^.Kind of
tkInteger, tkChar, tkEnumeration, tkWChar, tkSet:
begin
i := GetOrdProp(AObj, AProp);
Result := ShaCrcCompute(AOldCRC,@i, Sizeof(i));
end;
tkString, tkLString, tkUString:
begin
s := GetStrProp(AObj, AProp);
Result := ShaCrcCompute(AOldCRC, Pointer(s), s.Length * Sizeof(char));
end;
tkInt64:
begin
i64 := GetInt64Prop(AObj, AProp);
Result := ShaCrcCompute(AOldCRC,@i64, Sizeof(i64));
end;
tkWString:
begin
ws := GetWideStrProp(AObj, AProp);
Result := ShaCrcCompute(AOldCRC, Pointer(ws), Length(ws) * Sizeof(wchar));
end;
tkVariant:
begin
s := VarToStr(GetVariantProp(AObj, AProp));
Result := ShaCrcCompute(AOldCRC, Pointer(s), s.Length * Sizeof(char));
end;
tkFloat:
begin
f := GetFloatProp(AObj, AProp);
Result := ShaCrcCompute(AOldCRC,@f, Sizeof(f));
end;
else Result := AOldCRC;
end;
end;
function TObjectHelper.TUserDataObjProps.ComputeDataObjectCRC(
AObj: TObject): Cardinal;
var
Prop:PPropInfo;
begin
if not FCrcInit then InitCRC;
Result := cCRCINIT;
for Prop in FCRCProperties do
Result := ComputeValueCRC(Result, AObj, Prop);
Result := not Result;
end;
when I use the old rtti method (in TypInfo, Set/GetxxxProp family...) it's 5/6 times faster ! mostly is the TValue. Why ?
I writed a function in a class to scan all published properties (with rtti) and compute CRC 32bits on it ; my version with old rtti is 8 times faster than the new rtti ! unbelievable !!!
Unfortunately , for this example, I don't have the new rrti version (because too slow). but the old rtti (and the faster) is:
function ComputeValueCRC(AOldCRC:Cardinal; const AObj:TObject; AProp:PPropInfo):Cardinal;inline;
var
s:string;
ws:WideString;
i:Integer;
i64:int64;
f:Extended;
begin
case AProp^.PropType^^.Kind of
tkInteger, tkChar, tkEnumeration, tkWChar, tkSet:
begin
i := GetOrdProp(AObj, AProp);
Result := ShaCrcCompute(AOldCRC,@i, Sizeof(i));
end;
tkString, tkLString, tkUString:
begin
s := GetStrProp(AObj, AProp);
Result := ShaCrcCompute(AOldCRC, Pointer(s), s.Length * Sizeof(char));
end;
tkInt64:
begin
i64 := GetInt64Prop(AObj, AProp);
Result := ShaCrcCompute(AOldCRC,@i64, Sizeof(i64));
end;
tkWString:
begin
ws := GetWideStrProp(AObj, AProp);
Result := ShaCrcCompute(AOldCRC, Pointer(ws), Length(ws) * Sizeof(wchar));
end;
tkVariant:
begin
s := VarToStr(GetVariantProp(AObj, AProp));
Result := ShaCrcCompute(AOldCRC, Pointer(s), s.Length * Sizeof(char));
end;
tkFloat:
begin
f := GetFloatProp(AObj, AProp);
Result := ShaCrcCompute(AOldCRC,@f, Sizeof(f));
end;
else Result := AOldCRC;
end;
end;
function TObjectHelper.TUserDataObjProps.ComputeDataObjectCRC(
AObj: TObject): Cardinal;
var
Prop:PPropInfo;
begin
if not FCrcInit then InitCRC;
Result := cCRCINIT;
for Prop in FCRCProperties do
Result := ComputeValueCRC(Result, AObj, Prop);
Result := not Result;
end;
I hate TValue helpers. Every library has its own. Most of them do value conversion. My simple advice: If you write a library, do not use helpers. Things will get messed up, if you use more than one library.
ReplyDeleteMarkus Müller If the helpers are in some unit that is clearly separated from others that you might use when using the library I don't see an issue with that.
ReplyDeleteIf the library relies on using the helpers in your code that's wrong design though.
Markus Müller
ReplyDeleteActually the concept of helpers(partial classes) is the same as the traditional concept of library (namespaced library in this case). We all love and use libraries. Helpers are no different, as long as you use them properly and wisely ;-) . The only problem is that you can have only 1 helper at a time in Delphi :-( . I hope this gets fixed at some point.