Item 14. Lazy Optimization, Part 2: Introducing Laziness

I l @ ve RuBoard

Difficulty: 3

Copy-on-write is a common optimization. Do you know how to implement it?

Original::String (from Item 13) is all very well, but sometimes copies of string objects are taken, used without modification, and then discarded.

"It seems a shame," the implementer of Original::String from Item 13 might frown to herself, "that I always do all the work of allocating a new buffer (which can be expensive) when it may turn out that I never needed to if all the user does is read from the new string and then destroy it. I could have simply let the two string objects share a buffer under the covers, avoiding the copy for a while, and only really take a copy when I know I need to because one of the objects is going to try to modify the string. That way, if the user never modifies the copy, I never need to do the extra work!"

With a smile on her face and determination in her eyes, the implementer designs an Optimized::String that uses a copy-on-write implementation (also called "lazy copy"), implemented by reference-counting the underlying string representations:

 namespace Optimized {   class StringBuf   {   public:     StringBuf();             // start off empty    ~StringBuf();             // delete the buffer     void Reserve( size_t n );// ensure len >= n     char*    buf;            // allocated buffer     size_t   len;            // length of buffer     size_t   used;           // # chars actually used     unsigned refs;           // reference count   private:     // No copying...     //     StringBuf( const StringBuf& );     StringBuf& operator=( const StringBuf& );   };   class String   {   public:     String();                // start off empty    ~String();                // decrement reference count                              //  (delete buffer if refs==0)     String( const String& ); // point at same buffer and                              //  increment reference count     void   Append( char );   // append one character     // ... operator=() etc. omitted ...   private:     StringBuf* data_;     };   } 

Your assignment: Implement Optimized::StringBuf and Optimized::String . [1] You may want to add a private String::AboutToModify() helper function to simplify the logic.

[1] This Item incidentally illustrates another use for namespaces ”namely clearer exposition. It makes code easy and natural both to read as code and to talk about in human language. Writing the above description was much nicer than writing about differently named Original String and OptimizedString classes, never mind that those longer names would have made reading and writing the example code a little harder. Using namespaces judiciously can likewise improve readability in your production code and "talkability" during design meetings and code reviews.

I l @ ve RuBoard


More Exceptional C++
More Exceptional C++: 40 New Engineering Puzzles, Programming Problems, and Solutions
ISBN: 020170434X
EAN: 2147483647
Year: 2001
Pages: 118
Authors: Herb Sutter

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net