You are not logged in.
Pages: 1
hello Arnaud,
do you have a fast ASM function to do a Pos with mem pointers or array of bytes instead of strings? ( I want avoid the @uniquestring call each time Pcasting)
For 64bit of course
for example should be PosBin(SubStr:TBytes; Source: Pointer; Index:UInt64);
I can do in pascal using memcompare and indexes, but I know your crew is strong with ASM
let me know
thank you
Roberto
Offline
Shouldn't Source be a TBytes too?
Under x86/Win32 you can just reuse the PosEx() asm in SynCommons, and change the function declaration:
function PosBin(const SubStr, Source: TBytes; Offset: integer = 1): Integer;
asm
push ebx
push esi
push edx
test eax, eax
...
In fact, at least under x86, AnsiString and TBytes do have the same memory layout (if I remember correctly).
Under x64, I don't have asm at hand.
My guess is that two nested loops will be faster than calling CompareMem().
You may try this:
function PosBin(const SubStr, S: TBytes; Offset: PtrUInt = 1): Integer;
var len, lenSub: PtrInt;
ch: AnsiChar;
p, pSub, pStart, pStop: PAnsiChar;
label Loop0, Loop4, TestT, Test0, Test1, Test2, Test3, Test4,
AfterTestT, AfterTest0, Ret, Exit;
begin;
pSub := pointer(SubStr);
p := pointer(S);
if (p=nil) or (pSub=nil) or (Offset<1) then begin
Result := 0;
goto Exit;
end;
len := PDynArrayRec(Pointer(PtrInt(p)-STRRECSIZE))^.length;
lenSub := PDynArrayRec(Pointer(PtrInt(pSub)-STRRECSIZE))^.length-1;
if (len<lenSub+PtrInt(Offset)) or (lenSub<0) then begin
Result := 0;
goto Exit;
end;
pStop := p+len;
p := p+lenSub;
pSub := pSub+lenSub;
pStart := p;
p := p+Offset+3;
ch := pSub[0];
lenSub := -lenSub;
if p<pStop then goto Loop4;
p := p-4;
goto Loop0;
Loop4:
if ch=p[-4] then goto Test4;
if ch=p[-3] then goto Test3;
if ch=p[-2] then goto Test2;
if ch=p[-1] then goto Test1;
Loop0:
if ch=p[0] then goto Test0;
AfterTest0:
if ch=p[1] then goto TestT;
AfterTestT:
p := p+6;
if p<pStop then goto Loop4;
p := p-4;
if p<pStop then goto Loop0;
Result := 0;
goto Exit;
Test3: p := p-2;
Test1: p := p-2;
TestT: len := lenSub;
if lenSub<>0 then
repeat
if (psub[len]<>p[len+1]) or (psub[len+1]<>p[len+2]) then
goto AfterTestT;
len := len+2;
until len>=0;
p := p+2;
if p<=pStop then goto Ret;
Result := 0;
goto Exit;
Test4: p := p-2;
Test2: p := p-2;
Test0: len := lenSub;
if lenSub<>0 then
repeat
if (psub[len]<>p[len]) or (psub[len+1]<>p[len+1]) then
goto AfterTest0;
len := len+2;
until len>=0;
inc(p);
Ret:
Result := p-pStart;
Exit:
end;
Offline
very thanks
Offline
can I ask a courtesy?
Do you have tested this MM https://github.com/d-mozulyov/BrainMM ?
Will be nice see how it performs into a real life benchmark using the mormot multithreaded test...
I want see if it really scale so well, and the reliability.
Offline
I didn't test it yet.
Source code is nice - I like the single-unit approach.
Some design details (e.g. bit-based allocation instead of linked lists) is told to reduce memory consumption.
May be worth looking at in testing, perhaps not (yet) on production.
Anyway, we tried to avoid as much memory allocation as possible in mORMot units, so in practice, a good fast memory manager like FastMM4 gives good results, even on multi-threaded process.
Offline
Pages: 1