strlen eigenimplementierung?
-
@Ringding: Korrekter Code hat noch lange nichts mit performantem Code zu tun.
MfG SideWinder
-
Was hat das mit Performanz zu tun? Ich habe ja extra geschrieben, dass man es viel schneller machen kann, aber dann wird's natürlich auch komplizierter.
-
oder so ungefähr:
int strlen (char *p)
{
char *q = p;
while (*p++)
;
return p-q;
}
-
Ist zwar genau so langsam wie die vorigen Varianten, aber im Unterschied dazu nicht einmal korrekt.
-
Ringding schrieb:
Ist zwar genau so langsam wie die vorigen Varianten, aber im Unterschied dazu nicht einmal korrekt.
nicht? zählt der eins zu weit oder zu wenig?
-
Eins zu weit.
-
Ringding schrieb:
Eins zu weit.
aber wenn
char *p = "";
dan gibt der doch 0 raus, oder?
-
Ich weiss, eigentlich kein C++, aber bei sowas juckt mir immer der Assembler-Finger:
size_t strlen( const char* str ) { _asm { push edi push ecx pushfd cld mov edi,str mov ecx,0XFFFFFFFF xor al,al repne scasb sub edi,str mov eax,edi popfd pop ecx pop edi } }
-
Darf ich auch mal:
size_t strlen(const char* s) { const char* p = s; while (*p != '\0') ++p; return p - s; }Ein Implementierung von strlen bringt aber nichts, weil viele Compiler sowas intrinsic drauf haben.
-
EDIT: hat sich erledigt
-
Power Off schrieb:
size_t strlen( const char* str ) { _asm { push edi push ecx pushfd cld mov edi,str mov ecx,0XFFFFFFFF xor al,al repne scasb sub edi,str mov eax,edi popfd pop ecx pop edi } }size_t optimized_strlen (const char* string) { __asm { mov eax,string test al,0x03 jnz compare main_loop: mov edx,[eax] add eax,0x04 mov ecx,edx sub edx,0x01010101 and edx,0x80808080 jz main_loop not ecx and edx,ecx jz main_loop test dl,dl jnz lret1 test dh,dh jnz lret2 test edx,0x00FF0000 jnz lret3 jmp lret4 compare: add eax,0x04 test byte ptr [eax-0x04],0xFF jz lret1 test byte ptr [eax-0x03],0xFF jz lret2 test byte ptr [eax-02h],0xFF jz lret3 dec eax and al,0xFC jmp main_loop lret1: dec eax lret2: dec eax lret3: dec eax lret4: mov ecx,string dec eax sub eax,ecx }; }SCNR

-
audacia schrieb:
size_t optimized_strlen (const char* string) { __asm { mov eax,string test al,0x03 jnz compare main_loop: mov edx,[eax] add eax,0x04 mov ecx,edx sub edx,0x01010101 and edx,0x80808080 jz main_loop not ecx and edx,ecx jz main_loop test dl,dl jnz lret1 test dh,dh jnz lret2 test edx,0x00FF0000 jnz lret3 jmp lret4 compare: add eax,0x04 test byte ptr [eax-0x04],0xFF jz lret1 test byte ptr [eax-0x03],0xFF jz lret2 test byte ptr [eax-02h],0xFF jz lret3 dec eax and al,0xFC jmp main_loop lret1: dec eax lret2: dec eax lret3: dec eax lret4: mov ecx,string dec eax sub eax,ecx }; }SCNR

Cool!!

Ist das schneller als "rep scasb"?
(wegen der Anzahl der Micro-Ops?)
-
Power Off schrieb:
Ist das schneller als "rep scasb"?
(wegen der Anzahl der Micro-Ops?)Sollte schneller sein, da die Daten nicht byteweise, sondern immer als Doublewords geladen und erst in den Registern näher untersucht werden.