![]() |
TPerlRegEx - Performance
Wie ich ja bereits hier
![]() beschrieben habe, stelle ich eine Klassenbibliothek nach Unicode um, die reichlich Gebrauch von regulären Ausdrücken macht. In den Sourcen gibt es etliche Stellen, an denen implizit TPerlRegEx instanziert und nach Ausführung sofort wieder gelöscht wird. Das war früher mit einem alten PCRE-Wrapper auch kein Problem. In TPerlRegEx.create wird jedoch pcre_maketables aufgerufen. Da geht es dann los. [spekulier] Nachdem ich mir einen Wolf gegoogelt habe, scheint dieser Aufruf je nach Locale-Einstellung vier Tabellen von Zeichen zu erzeugen, die dann später für eine schnellere Umsetzung von Zeichenklassen in einem regulärem Ausdruck (\d \w usw.) dienen. [\spekulier] Überschreibt man den Konstruktor, ruft den geerbten nicht auf und macht ansonsten alle Initialisierungen, bleibt die Tabelle auf nil und es werden interne Defaulttabellen verwendet, deren Inhalt zur Kompilierzeit der C-Sourcen bestimmt wird. Ist dreimal so schnell und funktioniert auch fehlerfrei. In meinem alten Wrapper wurde dies ebenso gehandhabt. Trotzdem hätte ich gerne genauer verstanden, was es mit pcre_maketables im Zusammenhang mit den Locale-Einstelllungen auf sich hat. Gibt es hier wen, der sich mit pcre-Internas gut auskennt oder von einem Forum weiß, in dem man dazu Fragen stellen könnte? |
AW: TPerlRegEx - Performance
Keine Ahnung, aber das UTF-8 solltest du in den Options dennoch unbedingt setzen.
Isses so schneller? (siehe [edit/add])
Delphi-Quellcode:
Ansonsten wenigsten so:
type
TPerlRegEx2 = class(TPerlRegEx) private class var FTables: AnsiString; public constructor Create; end; constructor TPerlRegEx2.Create; begin if FTables = '' then FTables := pcre_maketables; FState := [preNotEmpty]; FCharTable := PAnsiChar(FTables); FPCREOptions := PCRE_UTF8 or PCRE_NEWLINE_ANY; end;
Delphi-Quellcode:
[edit]
constructor TPerlRegEx2.Create;
begin State := [preNotEmpty]; Options := [preCaseLess]; // einmal umschreiben, da sonst Änderung nicht übernommen wird Options := []; end; Mist, immer diese privaten Property, wo keiner mehr ran kommt. (warte mal ein Sekündchen) [add]
Delphi-Quellcode:
// erweiterte RTTI darf nicht deaktivert sein
uses RegularExpressionsAPI, RegularExpressionsCore, RTTI; type TPerlRegEx2 = class(TPerlRegEx) private class var FTables: PAnsiChar; public class constructor Create; class destructor Destroy; constructor Create; end; class constructor TPerlRegEx2.Create; begin FTables := pcre_maketables; end; class destructor TPerlRegEx2.Destroy; begin pcre_dispose(nil, nil, FTables); end; constructor TPerlRegEx2.Create; begin State := [preNotEmpty]; with TRttiContext.Create.GetType(TPerlRegEx2) do begin GetField('FCharTable').SetValue(Self, TValue.From<PAnsiChar>(FTables)); GetField('FPCREOptions').SetValue(Self, Integer(PCRE_UTF8 or PCRE_NEWLINE_ANY)); end; end; |
AW: TPerlRegEx - Performance
Guter Tipp. :)
Habe das jetzt so gelöst.
Code:
Das GetField musste noch weg, weil das ne Stringliste durchackert.
TPerlre = class(TPerlRegEx)
private class var FRttiContext : TRttiContext; FStaticCharTable : Pointer; FSCTField : TRttiField; ... class constructor TPerlre.create; begin FStaticCharTable := pcre_maketables; FSCTField:=FRttiContext.GetType(TPerlRe).GetField('FCharTable'); end; constructor TPerlre.Create(doStudy: boolean; opts: integer); begin FSCTField.SetValue(Self,TValue.From<Pointer>(FStaticCharTable)); ... end; procedure TPerlre.BeforeDestruction; begin inherited; FSCTField.SetValue(Self,TValue.From<Pointer>(nil)); // Weil TPerlRegEx.destroy sonst FCharTable freigeben will end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:59 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz