From e4f32886b34198d5620335b507e3ee5d0363d738 Mon Sep 17 00:00:00 2001 From: Nikhil R Deshpande Date: Fri, 12 Jun 2015 11:53:09 -0700 Subject: [PATCH 1/1] Remove unncessary localtime() calls during data type conversion While sending/fetching field of time data type to/from server, it might get converted to a data type that needs date part. In this case, the driver chooses to fill up the missing date part as current date, obtained through localtime() libc call. However this localtime() call is invoked for every combination of source and destination data types, and not just for above specific time->date[time] case. localtime() is not a cheap call (involves libc doing string processing and timezone conversion operations), and both send/fetch data paths are very high occurrence/hot code paths. This penalty adds up to significant impact on overall driver performance. --- convert.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/convert.c b/convert.c index 8802e6e..d22885a 100644 --- a/convert.c +++ b/convert.c @@ -912,16 +912,6 @@ copy_and_convert_field(StatementClass *stmt, memset(&std_time, 0, sizeof(SIMPLE_TIME)); - /* Initialize current date */ -#ifdef HAVE_LOCALTIME_R - tim = localtime_r(&stmt_t, &tm); -#else - tim = localtime(&stmt_t); -#endif /* HAVE_LOCALTIME_R */ - std_time.m = tim->tm_mon + 1; - std_time.d = tim->tm_mday; - std_time.y = tim->tm_year + 1900; - mylog("copy_and_convert: field_type = %d, fctype = %d, value = '%s', cbValueMax=%d\n", field_type, fCType, (value == NULL) ? "" : value, cbValueMax); if (!value) @@ -1017,6 +1007,17 @@ mylog("null_cvt_date_string=%d\n", conn->connInfo.cvt_null_date_string); case PG_TYPE_TIME: sscanf(value, "%2d:%2d:%2d", &std_time.hh, &std_time.mm, &std_time.ss); + /* Initialize date in case conversion destination + * expects date part from this source time data. + */ +#ifdef HAVE_LOCALTIME_R + tim = localtime_r(&stmt_t, &tm); +#else + tim = localtime(&stmt_t); +#endif /* HAVE_LOCALTIME_R */ + std_time.m = tim->tm_mon + 1; + std_time.d = tim->tm_mday; + std_time.y = tim->tm_year + 1900; break; case PG_TYPE_ABSTIME: @@ -4139,15 +4140,6 @@ inolog("ipara=%p paramType=%d %d proc_return=%d\n", ipara, ipara ? ipara->paramT param_string[0] = '\0'; cbuf[0] = '\0'; memset(&st, 0, sizeof(st)); - t = SC_get_time(qb->stmt); -#ifdef HAVE_LOCALTIME_R - tim = localtime_r(&t, &tm); -#else - tim = localtime(&t); -#endif /* HAVE_LOCALTIME_R */ - st.m = tim->tm_mon + 1; - st.d = tim->tm_mday; - st.y = tim->tm_year + 1900; ivstruct = (SQL_INTERVAL_STRUCT *) buffer; /* Convert input C type to a neutral format */ @@ -4290,7 +4282,18 @@ mylog("C_WCHAR=%s(%d)\n", buffer, used); st.hh = ts->hour; st.mm = ts->minute; st.ss = ts->second; - + /* Initialize date in case conversion destination + * expects date part from this source time data. + */ + t = SC_get_time(qb->stmt); +#ifdef HAVE_LOCALTIME_R + tim = localtime_r(&t, &tm); +#else + tim = localtime(&t); +#endif /* HAVE_LOCALTIME_R */ + st.m = tim->tm_mon + 1; + st.d = tim->tm_mday; + st.y = tim->tm_year + 1900; break; } -- 1.8.5.6