[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] Improve performance of svn_time_from_cstring

From: Brandon Ehle <azverkan_at_yahoo.com>
Date: 2002-12-03 19:32:01 CET

Here's the beef

Index: subversion/libsvn_subr/time.c
===================================================================
--- subversion/libsvn_subr/time.c (revision 3967)
+++ subversion/libsvn_subr/time.c (working copy)
@@ -142,6 +142,44 @@
   return -1;
 }
 
+/* Convert a number in a string into an unsigned integer quickly.
+ Note that this does not check for overflows. */
+/*static const char *
+fast_strtoui10(const char *s, unsigned int *result)
+{
+ int c;
+ unsigned int val = 0;
+
+ for (;;) {
+ c = *s - '0';
+ if (c < 0 || c > 9)
+ break;
+ val = val * 10 + c;
+ s++;
+ }
+ *result = val;
+ return s;
+}*/
+
+static unsigned long
+fast_strtoul10(const char **nptr)
+{
+ register const char *s=*nptr;
+ register int c;
+ register int found;
+ register unsigned long val=0;
+ while(1) {
+ c=*s++;
+ c -= '0';
+ if (c<0 || c>9)
+ break;
+ found = 1;
+ val *= 10;
+ val += c;
+ }
+ if(found) *nptr=s-1;
+ return val;
+}
 
 svn_error_t *
 svn_time_from_cstring(apr_time_t *when, const char *data, apr_pool_t *pool)
@@ -149,37 +187,44 @@
   apr_time_exp_t exploded_time;
   apr_status_t apr_err;
   char wday[4], month[4];
+ const char *c = data;
 
- /* First try the new timestamp format. */
- if (sscanf (data,
- timestamp_format,
- &exploded_time.tm_year,
- &exploded_time.tm_mon,
- &exploded_time.tm_mday,
- &exploded_time.tm_hour,
- &exploded_time.tm_min,
- &exploded_time.tm_sec,
- &exploded_time.tm_usec) == 7)
- {
- exploded_time.tm_year -= 1900;
- exploded_time.tm_mon -= 1;
- exploded_time.tm_wday = 0;
- exploded_time.tm_yday = 0;
- exploded_time.tm_isdst = 0;
- exploded_time.tm_gmtoff = 0;
-
- apr_err = apr_implode_gmt (when, &exploded_time);
- if(apr_err != APR_SUCCESS)
- {
- return svn_error_createf (SVN_ERR_BAD_DATE, apr_err, NULL,
- "Date conversion failed.");
- }
-
- return SVN_NO_ERROR;
- }
- /* Then try the compatibility option. */
- else if (sscanf (data,
- old_timestamp_format,
+ /* Open-code parsing of the new timestamp format, as this
+ is a hot path for reading the entries file. */
+ exploded_time.tm_year = fast_strtoul10(&c);
+ if (*c++ != '-') goto fail;
+ exploded_time.tm_mon = fast_strtoul10(&c);
+ if (*c++ != '-') goto fail;
+ exploded_time.tm_mday = fast_strtoul10(&c);
+ if (*c++ != 'T') goto fail;
+ exploded_time.tm_hour = fast_strtoul10(&c);
+ if (*c++ != ':') goto fail;
+ exploded_time.tm_min = fast_strtoul10(&c);
+ if (*c++ != ':') goto fail;
+ exploded_time.tm_sec = fast_strtoul10(&c);
+ if (*c++ != '.') goto fail;
+ exploded_time.tm_usec = fast_strtoul10(&c);
+ if (*c++ != 'Z') goto fail;
+
+ exploded_time.tm_year -= 1900;
+ exploded_time.tm_mon -= 1;
+ exploded_time.tm_wday = 0;
+ exploded_time.tm_yday = 0;
+ exploded_time.tm_isdst = 0;
+ exploded_time.tm_gmtoff = 0;
+
+ apr_err = apr_implode_gmt(when, &exploded_time);
+ if (apr_err == APR_SUCCESS)
+ return SVN_NO_ERROR;
+
+ return svn_error_createf(SVN_ERR_BAD_DATE, apr_err, NULL,
+ "Date conversion failed.");
+
+fail:
+ /* Try the compatibility option. This does not need to be fast,
+ as this format is no longer generated and the client will convert
+ an old-format entries file the first time it reads it. */
+ if (sscanf(data, old_timestamp_format,
                    wday,
                    &exploded_time.tm_mday,
                    month,
@@ -196,27 +241,22 @@
       exploded_time.tm_yday -= 1;
       /* Using hard coded limits for the arrays - they are going away
          soon in any case. */
- exploded_time.tm_wday = find_matching_string (wday, 7, apr_day_snames);
- exploded_time.tm_mon = find_matching_string (month, 12, apr_month_snames);
+ exploded_time.tm_wday = find_matching_string(wday, 7, apr_day_snames);
+ exploded_time.tm_mon = find_matching_string(month, 12, apr_month_snames);
 
- apr_err = apr_implode_gmt (when, &exploded_time);
- if(apr_err != APR_SUCCESS)
- {
- return svn_error_createf (SVN_ERR_BAD_DATE, apr_err, NULL,
- "Date conversion failed.");
- }
+ apr_err = apr_implode_gmt(when, &exploded_time);
+ if (apr_err == APR_SUCCESS)
+ return SVN_NO_ERROR;
 
- return SVN_NO_ERROR;
+ return svn_error_createf(SVN_ERR_BAD_DATE, apr_err, NULL,
+ "Date conversion failed.");
     }
+
   /* Timestamp is something we do not recognize. */
- else
- {
- return svn_error_createf(SVN_ERR_BAD_DATE, 0, NULL,
- "Date parsing failed.");
- }
+ return svn_error_createf(SVN_ERR_BAD_DATE, 0, NULL,
+ "Date parsing failed.");
 }
 
-
 const char *
 svn_time_to_human_cstring (apr_time_t t, apr_pool_t *pool)
 {

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Tue Dec 3 19:30:45 2002

This is an archived mail posted to the Subversion Dev mailing list.