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