Hello,

    The attached optimization patch was inspired be reviewing the
following code:

> Parser::parse(const SBuf &aBuf)
...
> if (preservedData_.isEmpty())
>     preservedData_ = aBuf; // avoid needless memory allocation
> else
>     preservedData_.append(aBuf);

Supporting this kind of optimization automatically was a little trickier
than I thought, but I think the attached patch does that. After the
patch, the above code will collapse to a single append call:

      preservedData_.append(aBuf);


HTH,

Alex.
P.S. AFAICT, there is no guarantee that SBuf using GetStorePrototype()
isEmpty so checking both conditions seems necessary to me.
Optimize appending to empty SBufs, a common use case.

Most appends start with an empty buffer. Some append only once. There
is no reason to allocate new memory for that first append or force the
appender to write code to optimize that first append.

Why also check that SBuf has never been configured or altered then? To
preserve pre-allocated SBufs, such as those [ab]used as I/O buffers.

=== modified file 'src/sbuf/SBuf.cc'
--- src/sbuf/SBuf.cc	2016-06-14 16:54:23 +0000
+++ src/sbuf/SBuf.cc	2016-10-06 15:29:26 +0000
@@ -170,40 +170,43 @@ SBuf::rawSpace(size_type minSpace)
 void
 SBuf::clear()
 {
 #if 0
     //enabling this code path, the store will be freed and reinitialized
     store_ = GetStorePrototype(); //uncomment to actually free storage upon clear()
 #else
     //enabling this code path, we try to release the store without deallocating it.
     // will be lazily reallocated if needed.
     if (store_->LockCount() == 1)
         store_->clear();
 #endif
     len_ = 0;
     off_ = 0;
     ++stats.clear;
 }
 
 SBuf&
 SBuf::append(const SBuf &S)
 {
+    if (isEmpty() && store_ == GetStorePrototype())
+        return (*this = S); // optimization: avoid needless copying
+
     const Locker blobKeeper(this, S.buf());
     return lowAppend(S.buf(), S.length());
 }
 
 SBuf &
 SBuf::append(const char * S, size_type Ssize)
 {
     const Locker blobKeeper(this, S);
     if (S == NULL)
         return *this;
     if (Ssize == SBuf::npos)
         Ssize = strlen(S);
     debugs(24, 7, "from c-string to id " << id);
     // coverity[access_dbuff_in_call]
     return lowAppend(S, Ssize);
 }
 
 SBuf &
 SBuf::append(const char c)
 {
_______________________________________________
squid-dev mailing list
squid-dev@lists.squid-cache.org
http://lists.squid-cache.org/listinfo/squid-dev

Reply via email to