>>>>> "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