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;

Comments

  1. 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.

    ReplyDelete
  2. Markus 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.
    If the library relies on using the helpers in your code that's wrong design though.

    ReplyDelete
  3. Markus Müller
    Actually 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.

    ReplyDelete

Post a Comment