[fpc-devel] rtti, arrays and performance
Vlad
vlad_mail_ru at mail.ru
Fri Oct 6 21:34:00 CEST 2006
Hi.
I'm porting my Delphi app to Mac OS X. Fortunately my core classes compile fine with freepascal, so I can produce dylib and use it from Cocoa application. To make binaries I use fpc 2.0.4 for powerpc version and fpc 2.1.1 for intel version (2.1.1 snapshot downloaded on August 2, 2006 from lazarus section). Recently I started to test performance and found that rtl spends quite a lot of time on array finalization. If you look into rtti.inc file you may see that it walks on array and trying to finalize each item even though it may need no finalization at all. Same with dynamic arrays. And with dynamic arrays similar problem may happen if rtl needs to add reference to each item in array but of cource it could be that items are not reference counted, so it will walk on array and will call appropriate function which just have nothing to do. To solve this issue I added function into "rtti.inc" which determines is data type dynamic (and therefore needs finalization and could be refrence counted) or not. It just recursively checks data types and returns TRUE if data type needs finalization. Then in ArrayRTTI and fpc_finalize_array I call this function to check is it neccessary to finalize each item or not. I added this function to "aliases.inc" and use it from "dynarr.inc" too - there two places where int_addref() function called for each array item, so, before doing this now for me it checks is that neccessary or not.
Perhaps the best way is to include some kind of attribute into type info and determine at compile time is data type has any dynamic part or not. Perhaps compiler may even not generate finalization calls for records (I don't know - maybe this is already done in compiler). But this could be much bigger amount of work
I can provide more info if you need. And I think that even such change is already better than nothing...
Best regards.
Vlad.
Here is the code of my procedure:
--------------------------------------------------------------------
function fpc_is_dyn_type( TypeInfo:Pointer ): boolean;[Public,Alias : 'FPC_IS_DYN_TYPE']; compilerproc;
var
Temp : pbyte;
namelen : byte;
count,
size,
i : SizeInt;
info : pointer;
begin
case PByte(TypeInfo)^ of
tkAstring, tkWstring, tkInterface, tkVariant, tkDynArray:
Result := true;
tkArray :
begin
Temp:=PByte(TypeInfo);
inc(Temp);
{ Skip Name }
namelen:=Temp^;
inc(temp,namelen+1);
temp:=aligntoptr(temp);
{ Skip Element size and count }
inc(Temp,2*sizeof(sizeint));
Result := fpc_is_dyn_type(PPointer(Temp)^);
end;
tkObject,
tkRecord:
begin
Temp:=PByte(TypeInfo);
inc(Temp);
{ Skip Name }
namelen:=Temp^;
inc(temp,namelen+1);
temp:=aligntoptr(temp);
{ Skip size }
inc(Temp,4);
{ Element count }
count:=PLongint(Temp)^;
inc(Temp,sizeof(longint));
{ Process elements }
for i:=1 to count Do
begin
Info:=PPointer(Temp)^;
{ Skip offset }
inc(Temp,sizeof(Info)+sizeof(longint));
if fpc_is_dyn_type(Info) then
begin
Result := true;
exit;
end;
end;
Result := false;
end;
else
Result := false;
end;
end;
----------------------------------------------------------------------
More information about the fpc-devel
mailing list