Re: Speedup usages of pg_*toa() functions
Ranier Vilela <ranier.vf@gmail.com>
From: Ranier Vilela <ranier.vf@gmail.com>
To: Andrew Gierth <andrew@tao11.riddles.org.uk>
Cc: David Rowley <dgrowleyml@gmail.com>, PostgreSQL Developers <pgsql-hackers@lists.postgresql.org>,
Andres Freund <andres@anarazel.de>
Date: 2020-06-09T18:37:57Z
Lists: 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 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
Commits
-
Have pg_itoa, pg_ltoa and pg_lltoa return the length of the string
- dad75eb4a8d5 14.0 landed
-
Add missing extern keyword for a couple of numutils functions
- 095f2d95c927 13.0 landed
- 9a7fccd9eac8 14.0 landed