Linked to the original question Is it possible to get the index of class property? and answered by Remy Lebeau and RRUZ
program Demo;
{$APPTYPE CONSOLE}
uses
System.SysUtils, Winapi.Windows,
System.Rtti, System.TypInfo;
type
TMyClass = class
private
function GetInteger(const Index: Integer): Integer;
procedure SetInteger(const Index, Value: Integer);
public
property P1: Integer Index 1 read GetInteger write SetInteger;
property P2: Integer Index 2 read GetInteger write SetInteger;
property P3: Integer Index 3 read GetInteger write SetInteger;
end;
{ TMyClass }
function TMyClass.GetInteger(const Index: Integer): Integer;
begin
Result := Index;
end;
procedure TMyClass.SetInteger(const Index, Value: Integer);
begin
//
end;
{------------------------------------------------------------------------------}
function GetPropertyIndex(const AClass: TClass; APropertyName: string): Integer;
var
Ctx: TRttiContext;
begin
Ctx := TRttiContext.Create;
Result := (Ctx.GetType(AClass).GetProperty(APropertyName) as TRttiInstanceProperty).Index;
end;
{------------------------------------------------------------------------------}
var
C: Cardinal;
I: Integer;
N: Integer;
begin
try
C := GetTickCount;
for N := 1 to 1000000 do
I := GetPropertyIndex(TMyClass, 'P2');
WriteLn(GetTickCount - C, ' ms - The index of the property P2 is ', I);
ReadLn;
except
on E: Exception do Writeln(E.ClassName, ': ', E.Message);
end;
end.
On my PC this test takes ~ 5 sec. But when I use TRttiContext
before calling GetPropertyIndex()
- for example
...
begin
try
TRttiContext.Create.Free;
C := GetTickCount;
for N := 1 to 1000000 do
I := GetPropertyIndex(TMyClass, 'P2');
...
same test takes only ~ 1 sec. Why ?
Edit The problem I found when I tested secon example as
...
var
Ctx: TRttiContext;
C: Cardinal;
I: Integer;
N: Integer;
begin
try
C := GetTickCount;
for N := 1 to 1000000 do
begin
Ctx := TRttiContext.Create;
I := (Ctx.GetType(TMyClass).GetProperty('P2') as TRttiInstanceProperty).Index;
end;
WriteLn(GetTickCount - C, ' ms - The index of the property P2 is ', I);
ReadLn;
except
on E: Exception do Writeln(E.ClassName, ': ', E.Message);
end;
end.
But the reason is more obvious in the second test as is the question.
TRttiContext.Create.Free;
in first not. It is added only to illustrate the problem. I edit my question, I have added the original test - it is more logical, but reason is not so obvious – KraskaTrttiContext.Create
orFree
. If you need to useTRttiContext
, just put it in a global variable. – Mammiemammiferous