Hi utime2gmt uses surprisingly much cpu, almost 10% according to gprof. It's fairly optimized, but it's called often with the same arguments. So let's add a cache for it.
In the worst case (no cache hit ever), the overhead for utime2gmt is little less than 1%. In the best case (cache hits always), drops utime2gmt cpu usage from 9.6% to 1.2%. Helps in mixed usage, since often accessed pages like the index page stay in the cache. - Lauri
>From 731bb8ef992ee6257b6b2595a9d9a5c793fa3853 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen <[email protected]> Date: Tue, 15 May 2012 14:49:15 +0300 Subject: [PATCH] utils: Add a gmt text cache for utime2gmt In the worst case (no cache hit ever), the overhead for utime2gmt is little less than 1%. In the best case (cache hits always), drops utime2gmt cpu usage from 9.6% to 1.2%. Helps in mixed usage, since often accessed pages like the index page stay in the cache. Signed-off-by: Lauri Kasanen <[email protected]> --- src/include/mk_cache.h | 1 + src/include/mk_utils.h | 9 ++++++++- src/mk_cache.c | 7 ++++++- src/mk_utils.c | 40 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/include/mk_cache.h b/src/include/mk_cache.h index d261234..dedd05b 100644 --- a/src/include/mk_cache.h +++ b/src/include/mk_cache.h @@ -31,6 +31,7 @@ pthread_key_t mk_cache_header_cl; pthread_key_t mk_cache_header_ka; pthread_key_t mk_cache_header_ka_max; pthread_key_t mk_cache_utils_gmtime; +pthread_key_t mk_cache_utils_gmt_text; struct mk_cache_date_t { diff --git a/src/include/mk_utils.h b/src/include/mk_utils.h index ba45621..3a15ace 100644 --- a/src/include/mk_utils.h +++ b/src/include/mk_utils.h @@ -36,6 +36,14 @@ #include "mk_memory.h" #include "mk_list.h" +#define MK_GMT_CACHES 10 + +struct mk_gmt_cache { + time_t time; + char text[32]; + unsigned long long hits; +}; + /* Trace definitions */ #ifdef TRACE @@ -45,7 +53,6 @@ #define MK_TRACE(...) mk_utils_trace(MK_TRACE_COMP_CORE, MK_TRACE_CORE, \ __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) - #include "mk_plugin.h" char *env_trace_filter; diff --git a/src/mk_cache.c b/src/mk_cache.c index 26a1525..82eea6a 100644 --- a/src/mk_cache.c +++ b/src/mk_cache.c @@ -41,7 +41,8 @@ void mk_cache_thread_init() struct tm *cache_utils_gmtime; struct mk_iov *cache_iov_header; - + struct mk_gmt_cache *cache_utils_gmt_text; + /* Cache header request -> last modified */ cache_header_lm = mk_mem_malloc_z(sizeof(mk_pointer)); cache_header_lm->data = mk_mem_malloc_z(32); @@ -74,6 +75,10 @@ void mk_cache_thread_init() /* Cache gmtime buffer */ cache_utils_gmtime = mk_mem_malloc(sizeof(struct tm)); pthread_setspecific(mk_cache_utils_gmtime, (void *) cache_utils_gmtime); + + /* Cache the most used text representations of utime2gmt */ + cache_utils_gmt_text = mk_mem_malloc_z(sizeof(struct mk_gmt_cache) * MK_GMT_CACHES); + pthread_setspecific(mk_cache_utils_gmt_text, (void *) cache_utils_gmt_text); } void *mk_cache_get(pthread_key_t key) diff --git a/src/mk_utils.c b/src/mk_utils.c index e8a8f87..ec26836 100644 --- a/src/mk_utils.c +++ b/src/mk_utils.c @@ -54,6 +54,37 @@ static const char *mk_date_wd[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", " static const char *mk_date_ym[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; +static int mk_utils_gmt_cache_get(char **data, time_t date) +{ + unsigned int i; + struct mk_gmt_cache *gcache = mk_cache_get(mk_cache_utils_gmt_text); + + for (i = 0; i < MK_GMT_CACHES; i++) { + if (date == gcache[i].time) { + memcpy(*data, gcache[i].text, 32); + gcache[i].hits++; + return MK_TRUE; + } + } + + return MK_FALSE; +} + +static void mk_utils_gmt_cache_add(char *data, time_t time) +{ + unsigned int i, min = 0; + struct mk_gmt_cache *gcache = mk_cache_get(mk_cache_utils_gmt_text); + + for (i = 1; i < MK_GMT_CACHES; i++) { + if (gcache[i].hits < gcache[min].hits) + min = i; + } + + gcache[min].hits = 1; + gcache[min].time = time; + memcpy(gcache[min].text, data, 32); +} + /* *This function given a unix time, set in a mk_pointer * the date in the RFC1123 format like: @@ -64,7 +95,7 @@ static const char *mk_date_ym[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", " */ int mk_utils_utime2gmt(char **data, time_t date) { - int size = 31; + const int size = 31; unsigned int year; char *buf=0; struct tm *gtm; @@ -75,6 +106,11 @@ int mk_utils_utime2gmt(char **data, time_t date) } } + /* Maybe it's converted already? */ + if (mk_utils_gmt_cache_get(data, date) == MK_TRUE) { + return size; + } + /* Convert unix time to struct tm */ gtm = mk_cache_get(mk_cache_utils_gmtime); @@ -139,6 +175,8 @@ int mk_utils_utime2gmt(char **data, time_t date) *buf++ = '\n'; *buf++ = '\0'; + mk_utils_gmt_cache_add(*data, date); + /* Set mk_pointer data len */ return size; } -- 1.7.2.1
_______________________________________________ Monkey mailing list [email protected] http://lists.monkey-project.com/listinfo/monkey
