Bug 50919 - potential performance waste caused by sprintf
Summary: potential performance waste caused by sprintf
Status: RESOLVED FIXED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: All (show other bugs)
Version: 2.2.17
Hardware: PC All
: P2 enhancement (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords: FixedInTrunk
Depends on:
Blocks:
 
Reported: 2011-03-12 17:14 UTC by Linhai Song
Modified: 2013-05-31 07:03 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Linhai Song 2011-03-12 17:14:31 UTC
/httpd-2.2.17/modules/loggers/mod_log_forensic.c:129
           sprintf(q, "%02x", *(unsigned char *)p);

After reading apache codes, I find this code fragment. Using this method to convert a number into a character which represents a hex number is very slow. 

I give out my patch as follows:

 static char hexmap[]= { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

 q = hexmap[*(unsigned char *)p]; 


In my unit test, my patch run as 7 times faster than the code fragment I find. If the code fragment will be executed many times, I believe it can slow down the whole application. 

I suggest that we should fix this bug.
Comment 1 William A. Rowe Jr. 2011-03-12 17:44:25 UTC
It appears you have compressed 2^8 bits into 2^4 bit representation, is that
what you meant to do?

Have you tested this with mapping to hexmap[(p >> 4)& 15] . hexmap[p & 15]...
and using a 256 char hexmap?
Comment 2 Linhai Song 2011-03-12 19:13:47 UTC
(In reply to comment #1)
> It appears you have compressed 2^8 bits into 2^4 bit representation, is that
> what you meant to do?
> 
> Have you tested this with mapping to hexmap[(p >> 4)& 15] . hexmap[p & 15]...
> and using a 256 char hexmap?

yes, this is what I mean


I write a wrong patch, and very sorry for the mistake.

the correct patch is 

static char _dig_vec_lower[]= { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a','b', 'c', 'd', 'e', 'f' };

static void array_to_hex( char * to , const char * str , unsigned char  len )
{

    const char * str_end = str + len;
    for( ; str != str_end ; ++ str )
    {
       *to++ = _dig_vec_lower[ ((unsigned char) *str) >> 4 ];
       *to++ = _dig_vec_lower[ ((unsigned char) *str) & 0x0F ];
    }
}

my unit test is using this patch, and it is more than 7 times faster than calling sprintf.
Comment 3 Christophe JAILLET 2013-01-06 18:09:48 UTC
Fixed in trunk.

http://svn.apache.org/viewvc?view=revision&sortby=date&revision=1429564
Comment 4 Christophe JAILLET 2013-05-31 07:03:24 UTC
Backported to 2.4.x: r1455222

Will be part of 2.4.5