httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Brian Pane <bp...@pacbell.net>
Subject [PATCH] performance patch for mod_log_config
Date Mon, 10 Sep 2001 02:46:30 GMT
The call to apr_explode_localtime() in mod_log_config is one of the more
expensive operations in the httpd.  This patch attempts to reduce the
overhead by caching the result.

--Brian


Index: modules/loggers/mod_log_config.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/loggers/mod_log_config.c,v
retrieving revision 1.68
diff -r1.68 mod_log_config.c
447a448,498
 >
 > /* Cache of expanded timestamps:
 >  *  Because apr_explode_localtime is an expensive function call,
 >  *  we cache the exploded time and re-use it for the rest of the
 >  *  current second.
 >  */
 >
 > struct exploded_time_cache_element {
 >     apr_int64_t t;
 >     apr_exploded_time_t xt;
 > };
 >
 > #define TIME_CACHE_SIZE 16
 > static struct exploded_time_cache_element 
exploded_time_cache[TIME_CACHE_SIZE];
 >
 > static void cached_explode_localtime(apr_exploded_time_t *xt, 
apr_time_t t)
 > {
 >     apr_int64_t seconds = t / APR_USEC_PER_SEC;
 >     struct exploded_time_cache_element *cache =
 >         &(exploded_time_cache[seconds % TIME_CACHE_SIZE]);
 >
 >     /* The cache is implemented as a ring buffer.  Each second,
 >      * it uses a different element in the buffer.  The timestamp
 >      * in the element indicates whether the element contains the
 >      * exploded time for the current second (vs the time
 >      * 'now - TIME_CACHE_SIZE' seconds ago).  If the cached
 >      * value is for the current time, we use it.  Otherwise,
 >      * we compute the apr_exploded_time_t and store it in this
 >      * cache element. Note that the timestamp in the cache
 >      * element is updated only after the exploded time.  Thus
 >      * if two threads hit this cache element simultaneously
 >      * at the start of a new second, they'll both explode the
 >      * time and store it.  I.e., the writers will collide, but
 >      * they'll be writing the same value.
 >      */
 >     if (cache->t >= seconds) {
 >         /* Note: If this memcpy ever takes more than TIME_CACHE_SIZE
 >          * seconds, the value will be unpredictable (because this
 >          * bucket in the ring buffer will have been recycled).
 >          * This memcpy should never take multiple seconds, but to
 >          * be safe we use a relatively large value for TIME_CACHE_SIZE.
 >          */
 >         memcpy(xt, &(cache->xt), sizeof(apr_exploded_time_t));
 >     }
 >     else {
 >         apr_explode_localtime(xt, t);
 >         memcpy(&(cache->xt), xt, sizeof(apr_exploded_time_t));
 >         cache->t = seconds;
 >     }
 > }
 >
466c517
<     apr_explode_localtime(&xt, apr_time_now());
---
 >     cached_explode_localtime(&xt, apr_time_now());
468c519
<     apr_explode_localtime(&xt, r->request_time);
---
 >     cached_explode_localtime(&xt, r->request_time);








Mime
View raw message