strlen eigenimplementierung?



  • camper schrieb:

    ich kenne mindestens einen compiler der hier tatsächlich zweimal pro durchgang inkrementiert.

    Was? Das darf aber wirklich nicht sein. So weit glaube ich den Standard doch zu kennen, dass ich meinen Code mit Sicherheit als korrekt hinstellen kann. Würde mich interessieren, welcher Compiler das ist.



  • @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.


Anmelden zum Antworten