[PATCH] libbb/last_char_is: rewrite for smaller and faster code

Tito farmatito at tiscali.it
Fri Jul 3 06:12:30 UTC 2020


On 7/3/20 4:58 AM, Jody Bruchon wrote:
> 
> 
> On July 2, 2020 3:26:29 PM EDT, Tito <farmatito at tiscali.it> wrote:
>> hi,
>> just for fun I add my version:
>>
>> char* FAST_FUNC last_char_is(const char *s, int c)  {
>> 	while (s && *s && *(s + 1)) s++;
>> 	return (c == *s) ? (char *)s : NULL;
>> }
> 
> That's pretty small, but it performs three comparisons for each character until
 the end and effectively scans the string twice in "parallel." If a bad pointer is passed in s, it'll segfault at the equality check in the return statement even though the first comparison is supposed to be a null pointer safeguard.
Hi,
Ops that slipped through, my copy-paste test case was wrong:

c = last_char_is("NULL", 'e');

Improved version:

char* last_char_is(const char *s, int c)  {
	if (!s || !*s) return NULL;
	while (*(s + 1))s++;
	return (c == *s) ? (char *)s : NULL;
}

or if you like gotos:

char* FAST_FUNC last_char_is(const char *s, int c)
{
	if (!s || !*s) goto OUT;
	while (*(s + 1))s++;
	if (c == *s) return (char *) s;
OUT:
	return NULL;
}

bloatcheck is same for both:
function                                             old     new   delta
last_char_is                                          53      42     -11
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-11)             Total: -11 bytes
   text    data     bss     dec     hex filename
 980860   16891    1872  999623   f40c7 busybox_old
 980849   16891    1872  999612   f40bc busybox_unstripped

Ciao,
Tito


More information about the busybox mailing list