gpt4 book ai didi

delphi - 为什么提前创建 TRttiContext 会使我的 RTTI 测试运行得更快?

转载 作者:行者123 更新时间:2023-12-03 15:42:07 25 4
gpt4 key购买 nike

链接到原始问题Is it possible to get the index of class property?由 Remy Lebeau 和 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.

在我的电脑上,此测试大约需要 5 秒。但是,当我在调用 GetPropertyIndex() 之前使用 TRttiContext 时 - 例如

...
begin
try
TRttiContext.Create.Free;

C := GetTickCount;
for N := 1 to 1000000 do
I := GetPropertyIndex(TMyClass, 'P2');
...

相同的测试只需约 1 秒。为什么?

编辑我在测试第二个示例时发现的问题

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

但是在第二次测试中,原因和问题一样更加明显。

最佳答案

RTTI 数据使用引用计数池进行缓存。您的代码速度如此之快的原因是 TRttiContext.Create.Free 语句创建了一个临时 TRttiContext,该临时 TRttiContext 在应用程序的生命周期内保持在范围内,从而维护事件引用到那个水池。在 GetPropertyIndex() 内部创建的后续 TRttiContext 实例将重复使用现有池,而不是每次都浪费时间重新创建新池。当 DPR 代码到达 end. 语句时,临时 TRttiContext 超出范围并释放其对池的引用。

当您删除 TRttiContext.Create.Free 语句时,临时 TRttiContext 就会消失,并且会为每个 TRttiContext 创建和销毁一个新池> GetPropertyIndex() 使用,浪费时间一遍又一遍地重新创建相同的缓存。

通过在“项目选项”中启用“调试 DCU”,然后单步执行调试器中的 TRttiContext 代码,您可以轻松查看实际情况。

关于delphi - 为什么提前创建 TRttiContext 会使我的 RTTI 测试运行得更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19722394/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com