The strncmp() call used to detect quad formatting
directives accounts for about 10% of the execution time
of the apr_*printf() functions. The static string used
in the comparison typically is only one or two characters
long, so calling a strcmp function is a very heavyweight
way to do the comparison.
This patch replaces the strncmp() with inline comparisons
of the one or two characters comprising the quad format
string. It works, but it's ugly.
Can anyone suggest a cleaner way of doing this?
--Brian
Index: strings/apr_snprintf.c
===================================================================
RCS file: /home/cvs/apr/strings/apr_snprintf.c,v
retrieving revision 1.22
diff -u -r1.22 apr_snprintf.c
--- strings/apr_snprintf.c 15 Mar 2002 17:42:05 -0000 1.22
+++ strings/apr_snprintf.c 2 May 2002 08:45:55 -0000
@@ -810,8 +810,15 @@
/*
* Modifier check
*/
+#if defined(APR_INT64_T_FMT_LEN) && (APR_INT64_T_FMT_LEN == 3)
+ if ((*fmt == APR_INT64_T_FMT[0]) &&
+ (fmt[1] == APR_INT64_T_FMT[1])) {
+#elif defined(APR_INT64_T_FMT_LEN) && (APR_INT64_T_FMT_LEN == 2)
+ if (*fmt == APR_INT64_T_FMT[0]) {
+#else
if (strncmp(fmt, APR_INT64_T_FMT,
sizeof(APR_INT64_T_FMT) - 2) == 0) {
+#endif
/* Need to account for trailing 'd' and null in sizeof() */
var_type = IS_QUAD;
fmt += (sizeof(APR_INT64_T_FMT) - 2);
Index: include/apr.h.in
===================================================================
RCS file: /home/cvs/apr/include/apr.h.in,v
retrieving revision 1.107
diff -u -r1.107 apr.h.in
--- include/apr.h.in 15 Apr 2002 05:55:24 -0000 1.107
+++ include/apr.h.in 2 May 2002 08:45:55 -0000
@@ -263,6 +263,7 @@
/* And APR_INT64_T_FMT */
@int64_t_fmt@
[EMAIL PROTECTED]@
/* are we going to force the generic atomic operations */
#define APR_FORCE_ATOMIC_GENERIC @apr_force_atomic_generic@
Index: configure.in
===================================================================
RCS file: /home/cvs/apr/configure.in,v
retrieving revision 1.444
diff -u -r1.444 configure.in
--- configure.in 1 May 2002 20:44:58 -0000 1.444
+++ configure.in 2 May 2002 08:45:56 -0000
@@ -1011,11 +1011,13 @@
if test "$ac_cv_sizeof_int" = "8"; then
int64_literal='#define APR_INT64_C(val) (val)'
int64_t_fmt='#define APR_INT64_T_FMT "d"'
+ int64_t_fmt_len='#define APR_INT64_T_FMT_LEN 1'
int64_value="int"
long_value=int
elif test "$ac_cv_sizeof_long" = "8"; then
int64_literal='#define APR_INT64_C(val) (val##L)'
int64_t_fmt='#define APR_INT64_T_FMT "ld"'
+ int64_t_fmt_len='#define APR_INT64_T_FMT_LEN 2'
int64_value="long"
long_value=long
elif test "$ac_cv_sizeof_long_long" = "8"; then
@@ -1025,16 +1027,19 @@
dnl doesn't support 'q'. Solaris wins. Exceptions can
dnl go to the OS-dependent section.
int64_t_fmt='#define APR_INT64_T_FMT "lld"'
+ int64_t_fmt_len='#define APR_INT64_T_FMT_LEN 3'
int64_value="long long"
long_value="long long"
elif test "$ac_cv_sizeof_long_double" = "8"; then
int64_literal='#define APR_INT64_C(val) (val##LD)'
int64_t_fmt='#define APR_INT64_T_FMT "Ld"'
+ int64_t_fmt_len='#define APR_INT64_T_FMT_LEN 2'
int64_value="long double"
long_value="long double"
elif test "$ac_cv_sizeof_longlong" = "8"; then
int64_literal='#define APR_INT64_C(val) (val##LL)'
int64_t_fmt='#define APR_INT64_T_FMT "qd"'
+ int64_t_fmt_len='#define APR_INT64_T_FMT_LEN 2'
int64_value="__int64"
long_value="__int64"
else
@@ -1042,6 +1047,7 @@
dnl # a 64-bit value but APR does not agree.
int64_literal='#error Can not determine the proper size for apr_int64_t'
int64_t_fmt='#error Can not determine the proper size for apr_int64_t'
+ int64_t_fmt_len='#error Can not determine the proper size for apr_int64_t'
fi
dnl # If present, allow the C99 macro INT64_C to override our conversion.
@@ -1174,6 +1180,7 @@
AC_SUBST(ssize_t_value)
AC_SUBST(socklen_t_value)
AC_SUBST(int64_t_fmt)
+AC_SUBST(int64_t_fmt_len)
AC_SUBST(ssize_t_fmt)
AC_SUBST(size_t_fmt)
AC_SUBST(off_t_fmt)