You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2010/05/05 13:01:40 UTC

svn commit: r941243 - in /subversion/trunk/subversion: include/svn_delta.h libsvn_delta/compose_delta.c libsvn_delta/svndiff.c libsvn_subr/checksum.c libsvn_subr/stream.c

Author: julianfoad
Date: Wed May  5 11:01:40 2010
New Revision: 941243

URL: http://svn.apache.org/viewvc?rev=941243&view=rev
Log:
Various local optimizations.  These opportunities became visible after
significantly optimizing other parts of svn.  The total savings for a 'svn
export' is almost 3 percent.

The largest savings can be attributed to the svndiff.c
changes (~1.5%) and the checksum parser (~1%).

* subversion/include/svn_delta.h
  (enum svn_delta_action): Document that these enum values must match the
    encoding values.

* subversion/libsvn_delta/compose_delta.c
  (search_offset_index, copy_source_ops): Use size_t to index memory. This
    is mainly a consistency fix but may actually result in slightly higher
    performance due to fewer conversions.

* subversion/libsvn_delta/svndiff.c
  (decode_file_offset, decode_size): Use slightly more efficient
    formulations.
  (decode_instruction): Directly map action codes, avoiding a 'switch'.

* subversion/libsvn_subr/checksum.c
  (svn_checksum_parse_hex): Eliminate calls to locale-aware CRT functions.
    At least with MS compilers, these are very expensive.

* subversion/libsvn_subr/stream.c
  (stream_readline): Hoist 'numbytes' from the loop: it is invariant until
    EOF.

Patch by: Stefan Fuhrmann <stefanfuhrmann{_AT_}alice-dsl.de>

Modified:
    subversion/trunk/subversion/include/svn_delta.h
    subversion/trunk/subversion/libsvn_delta/compose_delta.c
    subversion/trunk/subversion/libsvn_delta/svndiff.c
    subversion/trunk/subversion/libsvn_subr/checksum.c
    subversion/trunk/subversion/libsvn_subr/stream.c

Modified: subversion/trunk/subversion/include/svn_delta.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_delta.h?rev=941243&r1=941242&r2=941243&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_delta.h (original)
+++ subversion/trunk/subversion/include/svn_delta.h Wed May  5 11:01:40 2010
@@ -94,6 +94,9 @@ svn_delta_version(void);
 
 /** Action codes for text delta instructions. */
 enum svn_delta_action {
+    /* Note: The svndiff implementation relies on the values assigned in
+     * this enumeration matching the instruction encoding values. */
+
     /** Append the @a length bytes at @a offset in the source view to the
      * target.
      *

Modified: subversion/trunk/subversion/libsvn_delta/compose_delta.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_delta/compose_delta.c?rev=941243&r1=941242&r2=941243&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_delta/compose_delta.c (original)
+++ subversion/trunk/subversion/libsvn_delta/compose_delta.c Wed May  5 11:01:40 2010
@@ -165,10 +165,12 @@ create_offset_index(const svn_txdelta_wi
    as hint because most lookups come as a sequence of decreasing values
    for OFFSET and they concentrate on the lower end of the array. */
 
-static int
-search_offset_index(const offset_index_t *ndx, apr_size_t offset, int hint)
+static apr_size_t
+search_offset_index(const offset_index_t *ndx,
+                    apr_size_t offset,
+                    apr_size_t hint)
 {
-  int lo, hi, op;
+  apr_size_t lo, hi, op;
 
   assert(offset < ndx->offs[ndx->length]);
 
@@ -635,13 +637,13 @@ build_range_list(apr_size_t offset, apr_
 static void
 copy_source_ops(apr_size_t offset, apr_size_t limit,  
                 apr_size_t target_offset,
-                int hint,
+                apr_size_t hint,
                 svn_txdelta__ops_baton_t *build_baton,
                 const svn_txdelta_window_t *window,
                 const offset_index_t *ndx,
                 apr_pool_t *pool)
 {
-  int op_ndx = search_offset_index(ndx, offset, hint);
+  apr_size_t op_ndx = search_offset_index(ndx, offset, hint);
   for (;; ++op_ndx)
     {
       const svn_txdelta_op_t *const op = &window->ops[op_ndx];

Modified: subversion/trunk/subversion/libsvn_delta/svndiff.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_delta/svndiff.c?rev=941243&r1=941242&r2=941243&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_delta/svndiff.c (original)
+++ subversion/trunk/subversion/libsvn_delta/svndiff.c Wed May  5 11:01:40 2010
@@ -359,16 +359,27 @@ decode_file_offset(svn_filesize_t *val,
                    const unsigned char *p,
                    const unsigned char *end)
 {
+  svn_filesize_t temp = 0;
+
   if (p + MAX_ENCODED_INT_LEN < end)
     end = p + MAX_ENCODED_INT_LEN;
   /* Decode bytes until we're done.  */
-  *val = 0;
   while (p < end)
     {
-      *val = (*val << 7) | (*p & 0x7f);
-      if (((*p++ >> 7) & 0x1) == 0)
+      /* Don't use svn_filesize_t here, because this might be 64 bits
+       * on 32 bit targets. Optimizing compilers may or may not be
+       * able to reduce that to the effective code below. */
+      unsigned int c = *p++;
+
+      temp = (temp << 7) | (c & 0x7f);
+      if (c < 0x80)
+      {
+        *val = temp;
         return p;
+      }
     }
+
+  *val = temp;
   return NULL;
 }
 
@@ -379,16 +390,24 @@ decode_size(apr_size_t *val,
             const unsigned char *p,
             const unsigned char *end)
 {
+  apr_size_t temp = 0;
+
   if (p + MAX_ENCODED_INT_LEN < end)
     end = p + MAX_ENCODED_INT_LEN;
   /* Decode bytes until we're done.  */
-  *val = 0;
   while (p < end)
     {
-      *val = (*val << 7) | (*p & 0x7f);
-      if (((*p++ >> 7) & 0x1) == 0)
+      apr_size_t c = *p++;
+
+      temp = (temp << 7) | (c & 0x7f);
+      if (c < 0x80)
+      {
+        *val = temp;
         return p;
+      }
     }
+
+  *val = temp;
   return NULL;
 }
 
@@ -453,27 +472,33 @@ decode_instruction(svn_txdelta_op_t *op,
                    const unsigned char *p,
                    const unsigned char *end)
 {
+  apr_size_t c;
+  apr_size_t action;
+
   if (p == end)
     return NULL;
 
+  /* We need this more than once */
+  c = *p++;
+
   /* Decode the instruction selector.  */
-  switch ((*p >> 6) & 0x3)
-    {
-    case 0x0: op->action_code = svn_txdelta_source; break;
-    case 0x1: op->action_code = svn_txdelta_target; break;
-    case 0x2: op->action_code = svn_txdelta_new; break;
-    case 0x3: return NULL;
-    }
+  action = (c >> 6) & 0x3;
+  if (action >= 0x3)
+      return NULL;
+
+  /* This relies on enum svn_delta_action values to match and never to be
+     redefined. */
+  op->action_code = (enum svn_delta_action)(action);
 
   /* Decode the length and offset.  */
-  op->length = *p++ & 0x3f;
+  op->length = c & 0x3f;
   if (op->length == 0)
     {
       p = decode_size(&op->length, p, end);
       if (p == NULL)
         return NULL;
     }
-  if (op->action_code != svn_txdelta_new)
+  if (action != svn_txdelta_new)
     {
       p = decode_size(&op->offset, p, end);
       if (p == NULL)

Modified: subversion/trunk/subversion/libsvn_subr/checksum.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/checksum.c?rev=941243&r1=941242&r2=941243&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/checksum.c (original)
+++ subversion/trunk/subversion/libsvn_subr/checksum.c Wed May  5 11:01:40 2010
@@ -29,6 +29,7 @@
 
 #include "svn_checksum.h"
 #include "svn_error.h"
+#include "svn_ctype.h"
 
 #include "sha1.h"
 #include "md5.h"
@@ -206,12 +207,15 @@ svn_checksum_parse_hex(svn_checksum_t **
 
   for (i = 0; i < len; i++)
     {
-      if ((! isxdigit(hex[i * 2])) || (! isxdigit(hex[i * 2 + 1])))
+      if ((! svn_ctype_isxdigit(hex[i * 2])) ||
+          (! svn_ctype_isxdigit(hex[i * 2 + 1])))
         return svn_error_create(SVN_ERR_BAD_CHECKSUM_PARSE, NULL, NULL);
 
       ((unsigned char *)(*checksum)->digest)[i] =
-        (( isalpha(hex[i*2]) ? hex[i*2] - 'a' + 10 : hex[i*2] - '0') << 4) |
-        ( isalpha(hex[i*2+1]) ? hex[i*2+1] - 'a' + 10 : hex[i*2+1] - '0');
+        ((svn_ctype_isalpha(hex[i*2]) ? hex[i*2] - 'a' + 10
+                                      : hex[i*2] - '0') << 4) |
+        (svn_ctype_isalpha(hex[i*2+1]) ? hex[i*2+1] - 'a' + 10
+                                       : hex[i*2+1] - '0');
       is_zeros |= (*checksum)->digest[i];
     }
 

Modified: subversion/trunk/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/stream.c?rev=941243&r1=941242&r2=941243&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/stream.c (original)
+++ subversion/trunk/subversion/libsvn_subr/stream.c Wed May  5 11:01:40 2010
@@ -355,9 +355,9 @@ stream_readline(svn_stringbuf_t **string
 
       /* Read into STR up to and including the next EOL sequence. */
       match = eol_str;
+      numbytes = 1;
       while (*match)
         {
-          numbytes = 1;
           SVN_ERR(svn_stream_read(stream, &c, &numbytes));
           if (numbytes != 1)
             {