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.


Anmelden zum Antworten