[PATCH 3/3] resolv: Optimize inet_ntop

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Wed Jun 4 15:21:37 GMT 2025



On 04/06/25 05:09, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> -static const char *
>> +static inline const char *
>>  inet_ntop6 (const u_char *src, char *dst, socklen_t size)
>>  {
>>  	/*
>> @@ -108,7 +123,7 @@ inet_ntop6 (const u_char *src, char *dst, socklen_t size)
>>  	 */
>>  	char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
>>  	struct { int base, len; } best, cur;
>> -	u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
>> +	uint16_t words[NS_IN6ADDRSZ / NS_INT16SZ] = { 0 };
>>  	int i;
>>  
>>  	/*
>> @@ -116,7 +131,6 @@ inet_ntop6 (const u_char *src, char *dst, socklen_t size)
>>  	 *	Copy the input (bytewise) array into a wordwise array.
>>  	 *	Find the longest run of 0x00's in src[] for :: shorthanding.
>>  	 */
>> -	memset(words, '\0', sizeof words);
>>  	for (i = 0; i < NS_IN6ADDRSZ; i += 2)
>>  		words[i / 2] = (src[i] << 8) | src[i + 1];
> 
> The words copy shouldn't really be needed, GCC can usually combine two
> byte accesses into single 16-bit loads.

There is no need for the words array in fact, we can ntohs when
accessing the s6_addr16 for source (and on most chips it should be
lowered efficiently). 

> 
> It should be possible to optimize put_uint16 using SWAR techniques.  We
> don't need to do byte-wise output, either.  We can use full 32-bit
> writes, potentially with overlaps.

Not sure about that because the usual way is to present ipv6 in
quartet and using 32-bit would require to decompose it anyway.  Also
Paul's suggestion to do overlap writes showed mixed results on different
chips.

> 
> If the user-supplied output buffer has the maximum possible size, we
> don't need the temporary copy.  (This applies to the IPv4 variant, too.)
It shows a small performance increase, I have added this change.


More information about the Libc-alpha mailing list