Author: stefan2
Date: Thu Sep 30 00:01:45 2010
New Revision: 1002898
URL: http://svn.apache.org/viewvc?rev=1002898&view=rev
Log:
Merge r1001413 from the performance branch.
Improve documentation on svn_stringbuf_appendbyte.
Approved by: Hyrum K. Wright <hyrum_wright_at_mail.utexas.edu>
Modified:
subversion/trunk/ (props changed)
subversion/trunk/subversion/include/svn_string.h
subversion/trunk/subversion/libsvn_subr/svn_string.c
Propchange: subversion/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Sep 30 00:01:45 2010
@@ -23,7 +23,7 @@
/subversion/branches/log-g-performance:870941-871032
/subversion/branches/merge-skips-obstructions:874525-874615
/subversion/branches/nfc-nfd-aware-client:870276,870376
-/subversion/branches/performance:983764,983766,984927,985014,985037,985046,985669,987893,995507,995603
+/subversion/branches/performance:983764,983766,984927,985014,985037,985046,985669,987893,995507,995603,1001413
/subversion/branches/ra_serf-digest-authn:875693-876404
/subversion/branches/reintegrate-improvements:873853-874164
/subversion/branches/subtree-mergeinfo:876734-878766
Modified: subversion/trunk/subversion/include/svn_string.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_string.h?rev=1002898&r1=1002897&r2=1002898&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_string.h (original)
+++ subversion/trunk/subversion/include/svn_string.h Thu Sep 30 00:01:45 2010
@@ -254,6 +254,10 @@ void
svn_stringbuf_fillchar(svn_stringbuf_t *str, unsigned char c);
/** Append a single character @a byte onto @a targetstr.
+ * This is an optimized version of @ref svn_stringbuf_appendbytes
+ * that is much faster to call and execute. Gains vary with the ABI.
+ * The advantages extend beyond the actual call because the reduced
+ * register pressure allows for more optimization within the caller.
*
* reallocs if necessary. @a targetstr is affected, nothing else is.
* @since New in 1.7.
Modified: subversion/trunk/subversion/libsvn_subr/svn_string.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/svn_string.c?rev=1002898&r1=1002897&r2=1002898&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/svn_string.c (original)
+++ subversion/trunk/subversion/libsvn_subr/svn_string.c Thu Sep 30 00:01:45
2010
@@ -388,28 +388,60 @@ svn_stringbuf_ensure(svn_stringbuf_t *st
}
+/* WARNING - Optimized code ahead!
+ * This function has been hand-tuned for performance. Please read
+ * the comments below before modifying the code.
+ */
void
svn_stringbuf_appendbyte(svn_stringbuf_t *str, char byte)
{
+ char *dest;
+ apr_size_t old_len = str->len;
+
/* In most cases, there will be pre-allocated memory left
* to just write the new byte at the end of the used section
* and terminate the string properly.
*/
- apr_size_t old_len = str->len;
- if (str->blocksize > old_len + 1)
+ if (str->blocksize < old_len + 1)
{
- char *dest = str->data;
+ /* The following read does not depend this write, so we
+ * can issue the write first to minimize register pressure:
+ * The value of old_len+1 is no longer needed; on most processors,
+ * dest[old_len+1] will be calculated implicitly as part of
+ * the addressing scheme.
+ */
+ str->len = old_len+1;
+
+ /* Since the compiler cannot be sure that *src->data and *src
+ * don't overlap, we read src->data *once* before writing
+ * to *src->data. Replacing dest with str->data would force
+ * the compiler to read it again after the first byte.
+ */
+ dest = str->data;
+ /* If not already available in a register as per ABI, load
+ * "byte" into the register (e.g. the one freed from old_len+1),
+ * then write it to the string buffer and terminate it properly.
+ *
+ * Including the "byte" fetch, all operations so far could be
+ * issued at once and be scheduled at the CPU's descression.
+ * Most likely, no-one will soon depend on the data that will be
+ * written in this function. So, no stalls there, either.
+ */
dest[old_len] = byte;
dest[old_len+1] = '\0';
-
- str->len = old_len+1;
}
else
{
/* we need to re-allocate the string buffer
* -> let the more generic implementation take care of that part
*/
+
+ /* Depending on the ABI, "byte" is a register value. If we were
+ * to take its address directly, the compiler might decide to
+ * put in on the stack *unconditionally*, even if that would
+ * only be necessary for this block.
+ */
char b = byte;
svn_stringbuf_appendbytes(str, &b, 1);
}