uROTypes.FindROClass implements a linear search over all registered TROComplexType classes. It is invoked by TROStreamSerializer at deserialization for every TROComplexType descendant.
For small messages and few registered TROComplexType classes this may be adequate.
In our project there are more than 600 registered TROComplexTypes, and we have messages with arrays containing thousands of TROComplexType descendants.
In this case, the linear search in FindROClass is inadequate. We patched it and replaced it with a hashtable based implementation.
Result of a test (640 registered TROComplexType classes, deserialization of ~7000 TROComplexType descendants):
Without optimization: 100% serialization execution time
With optimization: 65% serialization execution time
We would be glad to see a similar improvement in the original RemObjects SDK code base.
can you upload your testcase that shows that uROTypes.FindROClass isn’t optimized, pls?
as I see, we use standard TStringList.IndexOf that uses quicksort
var
_ComplexTypes : TList{$IFDEF NEXTGEN}<TROComplexTypeClass>{$ENDIF};
//...
function FindROClass(const aClassName: string): TROComplexTypeClass;
var
i: Integer;
begin
Result := nil;
for i := 0 to (_ComplexTypes.Count-1) do begin
if (CompareText(TClass(_ComplexTypes.Items[i]).ClassName, aClassName)=0) then begin
Result := TROComplexTypeClass(_ComplexTypes.Items[I]);
Break;
end;
end;
end;
From RemObjects 9.0.97.1245, uROTypes.pas:
var
_ComplexTypes : TList{$IFDEF NEXTGEN}<TROComplexTypeClass>{$ENDIF};
//...
function FindROClass(const aClassName: string): TROComplexTypeClass;
var
i: Integer;
begin
for i := 0 to (_ComplexTypes.Count-1) do begin
if (CompareText(TClass(_ComplexTypes.Items[i]).ClassName, aClassName)=0) then begin
Result := TROComplexTypeClass(_ComplexTypes.Items[I]);
Exit;
end;
end;
{$IFDEF RO_RTTI_Support}
Result := RORTTI_FindROClass(aClassName)
{$ELSE}
Result := nil;
{$ENDIF}
end;
for i := 0 to _ComplexTypes_new.Count-1 do begin
if list1.IndexOf(_ComplexTypes_new[i]) <> -1 then Continue; // already processed
//_TMyComplexList = {$IFDEF NEXTGEN}TDictionary<String,TROComplexTypeClass>{$ELSE}TStringList{$ENDIF};
List := _TMyComplexList(_ComplexTypes_new.Objects[i]);
{$IFDEF NEXTGEN}
if List.ContainsKey(aClassName) then begin
Result := List.Items[aClassName];
Exit;
end;
{$ELSE}
j := List.IndexOf(aClassName);
if j <> -1 then begin
Result := TROComplexTypeClass(List.Objects[j]);
Exit;
end;
{$ENDIF}
end;