httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christophe JAILLET <christophe.jail...@wanadoo.fr>
Subject Re: ap_casecmpstr()
Date Thu, 21 Jan 2016 20:15:11 GMT
Le 21/01/2016 17:48, Jim Jagielski a écrit :
> Where are we with this? Trunk uses this. Should a backport
> proposal be done for 2.4??
>
+++1
(trying to keep trunk and 2.4.x more or less in line will be a nightmare 
as long as this is not synch)



BTW, one of my reticence for such a big patch was related to the fact 
that apr_table_ functions would not get the speed increase. So why 
bother for just a "half patch" ?
I was wrong.
apr_table_ functions first make a quick, case insensitive, test using 
the COMPUTE_KEY_CHECKSUM macro.

Here, the case-insensitive test is not made byte by byte using a lookup 
table, but up to the 4 first bytes are converted to uppercase using a "& 
0xdf".
The "slow" strcasecmp is only performed afterwards if these 4 bytes 
don't match.


Such an implementation could be benchmarked against latest Yann's 
version to see if a few test/shift/and statements perform better than 
memory access in a lookup table.


This also means that APR is already a mix of "ASCII case-folding, POSIX 
compliant" (i.e. takes advantage of upper = lower & 0xdf) and local 
codepage aware functions (i.e. strcasecmp) when using apr_table_ functions.

CJ


+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

#if APR_CHARSET_EBCDIC
#define CASE_MASK 0xbfbfbfbf
#else
#define CASE_MASK 0xdfdfdfdf
#endif

[...]

/* Compute the "checksum" for a key, consisting of the first
  * 4 bytes, normalized for case-insensitivity and packed into
  * an int...this checksum allows us to do a single integer
  * comparison as a fast check to determine whether we can
  * skip a strcasecmp
  */
#define COMPUTE_KEY_CHECKSUM(key, checksum)    \
{                                              \
     const char *k = (key);                     \
     apr_uint32_t c = (apr_uint32_t)*k;         \
     (checksum) = c;                            \
     (checksum) <<= 8;                          \
     if (c) {                                   \
         c = (apr_uint32_t)*++k;                \
         checksum |= c;                         \
     }                                          \
     (checksum) <<= 8;                          \
     if (c) {                                   \
         c = (apr_uint32_t)*++k;                \
         checksum |= c;                         \
     }                                          \
     (checksum) <<= 8;                          \
     if (c) {                                   \
         c = (apr_uint32_t)*++k;                \
         checksum |= c;                         \
     }                                          \
     checksum &= CASE_MASK;                     \
}


Mime
View raw message