Liebe Delphi Community!
Ich entwickle in MS Accees mit VBA und beschäftige mich seit wenigen Tagen mit Delphi.
Hauptzweck ist bisher das Schreiben von
DLL um die Performance innerhalb von VBA zu verbessern
und die Möglichkeiten zu erweitern.
Ich habe einige kleine Scripte erstellt und Performance Vergleiche angestellt.
Ist grundsätzlich zu erwarten, dass ich mit Delphi
DLL ähnliche Performace wie mit
WinAPI erreichen kann?
Hier zwei Scripte mit dem selben Ziel. Die Suche nach einer Chargruppe in einem String und das Ersetzen durch ein anderes Zeichen.
Hier ein Teil der ersten Funktion, die mittels
API StrCSpnW das Vorkommen im String sucht:
Übergeben werden aus VBA drei StringsPointer und eine Pointer auf einen StringPointer für die Rückgabe an VBA.
Code:
function ReplCharGroup(Text, CharGroup, Repl:PWideChar; ResString:PInteger):integer;stdcall;
var
lText, lChars, lRepl, f, lMem:Integer;
p, r, rp:PWideChar;
begin
lChars:=BstrLen(CharGroup^);
lText:= BstrLen(Text^);
lRepl:= BstrLen(Repl^);
result:=0;
//kein Text
if ltext = 0 then Exit(1);
if lChars = 0 then Exit(2);
f:=StrCSpnW(Text, CharGroup);
if f=lText then begin
SysReAllocStringLen(ResString^, Text^, lText);
Exit;
end;
if lRepl=1 then begin
SysReAllocStringLen(ResString^, Text^, lText);
p:=PWideChar(ResString^);
repeat
inc(p, f);
p^:=Repl^;
inc(p);
dec(lText, f+1);
f:=StrCSpnW(p, CharGroup);
until lText = f ;
end
Hier eine Variante die direkt nach dem Vorkommen sucht:
Code:
function CharInGroup(var Text:PWideChar; CharGroup:PWideChar; const lText, lChars :Integer; Position:Integer):integer;inline;
var t,c,r:integer;
begin
for t := Position to lText do begin
for c := 1 to lChars do begin
if chargroup^ = text^ then
exit(t)
else
inc(chargroup);
end;
inc(Text);
dec(Chargroup, lChars);
end;
result:=0;
end;
function ReplCharGroup2(Text, CharGroup, Repl:PWideChar; ResString:PInteger):integer; stdcall;
var
lText, lChars, lRepl, f, fOld, lMem:Integer;
p, r, rp:PWideChar;
begin
lChars:=BstrLen(CharGroup^);
lText:= BstrLen(Text^);
lRepl:= BstrLen(Repl^);
fold:=1;
result:=0;
//kein Text
if ltext = 0 then Exit(1);
if lChars = 0 then Exit(2);
if lRepl=1 then begin
SysReAllocStringLen(ResString^, Text^, lText);
p:=PWideChar(ResString^);
f:=CharInGroup(p,CharGroup, lText, lChars,fold);
if f=0 then Exit;
repeat
p^:=Repl^;
fold:=f+1;
inc(p);
f:=CharInGroup(p,CharGroup, lText, lChars,fold);
until f=0;
end
API Deklarationen:
Code:
Function StrCSpnW (StrPtr, Charset:PWideChar):Integer; stdcall;external 'Shlwapi';
Function SysReAllocStringLen (var BSTR, StrPtr; Letters: Integer):LongWord; stdcall;external 'OleAut32';
Function BstrLen (var StrPtr):integer;stdcall;external 'oleaut32' name 'SysStringLen';
Es funktionieren beide Codes ohne Probleme und wie gesagt es sind nur Teile der Funktion (aber vollständig, was das ersetzen durch ein Zeichen anbelangt).
Allerdings steigt der Zeitbedarf der selbst geschriebene Suche exponential gegenüber der Suche mittels
API.
Kann ich die Performance von CharInGroup erhöhen?
Danke für Eure Mühe.
LG Markus