Re: Speedup usages of pg_*toa() functions

Поиск
Список
Период
Сортировка
От Ranier Vilela
Тема Re: Speedup usages of pg_*toa() functions
Дата
Msg-id CAEudQAoKAZ1GNNb_wkKmYTqvbkbYEHP97OhOW-Hi_1kMpmg3+g@mail.gmail.com
обсуждение исходный текст
Ответ на Re: Speedup usages of pg_*toa() functions  (Andrew Gierth <andrew@tao11.riddles.org.uk>)
Ответы Re: Speedup usages of pg_*toa() functions  (Andrew Gierth <andrew@tao11.riddles.org.uk>)
Список pgsql-hackers
Em ter., 9 de jun. de 2020 às 13:01, Andrew Gierth <andrew@tao11.riddles.org.uk> escreveu:
>>>>> "Ranier" == Ranier Vilela <ranier.vf@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     edxedi
        xor     eaxeax
        mov     rdirsi
        mov     esiOFFSET FLAT:.LC0
        jmp     sprintf
pg_toa(int, char*):
        push    rbp
        test    ediedi
        mov     rbprsi
        mov     edxedi
        mov     esiOFFSET FLAT:.LC0
        mov     rdirbp
        mov     eax0
        js      .L7
        pop     rbp
        jmp     sprintf
.L7:
        call    sprintf
        movsx   rdxeax
        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

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Jeff Davis
Дата:
Сообщение: Re: Disallow cancellation of waiting for synchronous replication
Следующее
От: Andrew Gierth
Дата:
Сообщение: Re: Speedup usages of pg_*toa() functions