Em ter., 9 de jun. de 2020 às 13:01, Andrew Gierth <
and...@tao11.riddles.org.uk> escreveu:

> >>>>> "Ranier" == Ranier Vilela <ranier...@gmail.com> writes:
>
>  Ranier> Written like that, wouldn't it get better?
>
>  Ranier> int
>  Ranier> pg_lltoa(int64 value, char *a)
>  Ranier> {
>  Ranier>     if (value < 0)
>  Ranier>     {
>  Ranier>         int         len = 0;
>  Ranier>         uint64      uvalue = (uint64) 0 - uvalue;
>  Ranier>         a[len++] = '-';
>  Ranier>         len += pg_ulltoa_n(uvalue, a + len);
>  Ranier>         a[len] = '\0';
>  Ranier>         return len;
>  Ranier>     }
>  Ranier>     else
>  Ranier>         return pg_ulltoa_n(value, a);
>  Ranier> }
>
> No. While it doesn't matter so much for pg_lltoa since that's unlikely
> to inline multiple pg_ulltoa_n calls, if you do pg_ltoa like this it (a)
> ends up with two copies of pg_ultoa_n inlined into it, and (b) you don't
> actually save any useful amount of time. Your version is also failing to
> add the terminating '\0' for the positive case and has other obvious
> bugs.
>
(a) Sorry, I'm not asm specialist.

#include <stdio.h>

int pg_utoa(unsigned int num, char * a) {
    int len;

    len = sprintf(a, "%lu", num);

    return len;
}

int pg_toa(int num, char * a)
{
    if (num < 0) {
       int len;
       len = pg_utoa(num, a);
       a[len] = '\0';
       return len;
    }
    else
       return pg_utoa(num, a);
}


.LC0:
        .string "%lu"
pg_utoa(unsigned int, char*):
        mov     edx, edi
        xor     eax, eax
        mov     rdi, rsi
        mov     esi, OFFSET FLAT:.LC0
        jmp     sprintf
pg_toa(int, char*):
        push    rbp
        test    edi, edi
        mov     rbp, rsi
        mov     edx, edi
        mov     esi, OFFSET FLAT:.LC0
        mov     rdi, rbp
        mov     eax, 0
        js      .L7
        pop     rbp
        jmp     sprintf
.L7:
        call    sprintf
        movsx   rdx, eax
        mov     BYTE PTR [rbp+0+rdx], 0
        pop     rbp
        ret

Where " ends up with two copies of pg_ultoa_n inlined into it", in this
simplified example?

(b) I call this tail cut, I believe it saves time, for sure.

Regarding bugs:

(c) your version don't check size of a var, when pg_ulltoa_n
warning about "least MAXINT8LEN bytes."

So in theory, I could blow it up, by calling pg_lltoa.

(d) So I can't trust pg_ulltoa_n, when var a, is it big enough?
If not, there are more bugs.

regards,
Ranier Vilela

Reply via email to