Es ist, wie Sie Ihre eigenen New()
und Dispose()
Funktionen zu schreiben, mit Ihrer eigenen Rekord Initialisierung/Fertigstellung:
uses
TypInfo;
procedure RecordInitialize(Dest, TypeInfo: pointer);
asm
{$ifdef CPUX64}
.NOFRAME
{$endif}
jmp [email protected]
end;
procedure RecordClear(Dest, TypeInfo: pointer);
asm
{$ifdef CPUX64}
.NOFRAME
{$endif}
jmp [email protected]
end;
function NewRec1(TypeInfo: pointer): pointer;
begin
GetMem(result, GetTypeData(TypeInfo)^.RecSize);
RecordInitialize(result, TypeInfo);
end;
function NewRec2(TypeInfo: pointer): pointer;
var
len: integer;
begin
len := GetTypeData(TypeInfo)^.RecSize;
GetMem(result, len);
FillChar(result^, len, 0);
end;
procedure NewDispose(Rec: pointer; TypeInfo: Pointer);
begin
RecordClear(Rec, TypeInfo);
FreeMem(Rec);
end;
Erstens gibt es einen Low-Level-asm Trick, um die verborgenen inneren Funktionen aufzurufen wir brauchen.
Ich schlage dann zwei Möglichkeiten der Initialisierung des Datensatzes vor, einen mit [email protected]
, den anderen mit FillChar
. Beachten Sie außerdem, dass die Initialisierung/Finalisierung der Elemente automatisch erfolgt, wenn Sie Ihre Datensätze in einem dynamischen Array zuweisen. Und die Initialisierung ruft nicht Initialize()
sondern FillChar
auf, um den Speicher mit Nullen zu füllen.
Es ist schade, dass wir globale Funktionen/Prozeduren mit generischen Parametern nicht definieren konnten, sonst könnten wir den Parameter TypeInfo()
loswerden.
Vor einigen Jahren schrieb ich die RTL part of record initialization/finalization für schnellere Ausführung neu. Beachten Sie, dass TObject
würde FinalizeRecord
aufrufen, so ist es ein Teil der RTL, die Verstärkung optimiert werden. Der Compiler sollte den Code ausgeben, anstatt die RTTI zu verwenden - aber zumindest sollte die RTL ein bisschen mehr optimiert werden.
Wenn Sie unsere Open Source SynCommons.pas
Gerät verwenden, und legen Sie die DOPATCHTRTL
bedingten für Ihr Projekt finden Sie im Prozess Patch der FillChar Move RecordCopy FinalizeRecord InitializeRecord TObject.CleanupInstance
Low-Level-Funktionen RTL haben, die asssembly optimiert verwenden würde, und SSE2 Opcodes, falls verfügbar.
Danke David. Könnte man eine schnellere Implementierung für einen bestimmten Datensatztyp schreiben? –
Bei verwaltetem Typ würde ein Aufruf von 'GetMem' gefolgt von einer Nullstellung des Speichers oft schneller sein. Für unmanaged Typen gibt es nichts zu gewinnen. –
Ich denke ich verstehe jetzt. –