设为首页 加入收藏

TOP

条款14:缓式优化,之二:(1)
2013-10-07 14:02:41 来源: 作者: 【 】 浏览:63
Tags:条款 优化 之二

条款14:缓式优化,之二:(1)

引入缓式优化 难度:3

copy-on-write是一种常用的优化技术,你知道如何实现它吗?

Original::String(见条款13)好倒是好,但有时候,在得到一个字符串对象的复制对象后,用户可能不会在使用中对它做任何修改,然后又把它丢弃了。

"这好像有点丢人,"条款13中Original::String的设计者可能会对自己不 满,"我每次都做了分配新缓冲区的所有工作(开销会很昂贵),可是,如果所有用户只是从新字符串中读取数据然后将其摧毁,那么,我所做的其实完全没有必要。我可以只是让两个字符串对象在底层共享一个缓冲区,暂时避免复制操作;只是在确实知道需要复制的时候,也就是,当其中一个对象试图修改这个字符串的时候,我才进行复制。采用这种方法,如果用户永远不修改这个复制对象,我就永远不用做额外的工作!"

脸上带着微笑,眼里充满着坚定,这个程序员设计了一个Optimized::String,他使用了一个copy-on-write实现(也称"缓式复制"),对底层字符串实体实施引用计数:

  1. namespace Optimized  
  2. {  
  3. class StringBuf  
  4. {  
  5. public:  
  6. StringBuf();                        // 开始为空  
  7. ~StringBuf();                       // 删除缓冲区  
  8. void Reserve( size_t n );   // 保证len >= n  
  9.  
  10. char*    buf;                   // 分配的缓冲区  
  11. size_t  len;                    // 缓冲区长度  
  12. size_t  used;                   // 实际使用的字符数量  
  13. unsigned refs;              // 引用计数  
  14.  
  15. private:  
  16. // 禁止复制 ...  
  17. //  
  18. StringBuf( const StringBuf& );  
  19. StringBuf& operator=( const StringBuf& );  
  20. };  
  21.  
  22. class String  
  23. {  
  24. public:  
  25. String();                       // 开始为空  
  26. ~String();                      // 递减引用计数  
  27.     //(如果refs==0则删除缓冲区)  
  28. String( const String& );    // 指向同一缓冲区  
  29.         // 并递增引用计数  
  30. void  Append( char );           // 增添一个字符  
  31.  
  32. // ...省略operator=()等...  
  33.  
  34. private:  
  35. StringBuf* data_;  
  36. };  

你的任务是:实现Optimized::StringBuf和Optimized::String。  你可能需要增加一个私有的String::AboutToModify()辅助函数,以简化处理逻辑。

解答

首先看看StringBuf。注意,默认的以成员为单位的复制和赋值操作对于StringBuf来说没有意义,所以二者都被禁止掉了(声明为private但没有定义)。

这里,Optimized::StringBuf所完成的工作正是当初Original::String所做工作的一部分。StringBuf的默认构造函数和析构函数正如你所估计的那样:

  1. namespace Optimized  
  2. {  
  3.  
  4. StringBuf::StringBuf() : buf(0), len(0), used(0), refs(1) { }  
  5.  
  6. StringBuf::~StringBuf() { delete[] buf; }  
  7. Reserve()也和 Original::String中的那个类似:  
  8. void StringBuf::Reserve( size_t n )  
  9. {  
  10. if ( len < n )  
  11. {  
  12. size_t newlen = max ( len* 1.5, n );  
  13. char*   newnewbuf = new char[ newlen ];  
  14. copy( buf, buf+used, newbuf );  
  15.  
  16. delete[] buf;   // 现在,所有实际工作已经完成,  
  17. buf = newbuf;  // 所以,获得拥有权  
  18. len = newlen;  
  19. }  

StringBuf就这些。

再看看String本身。默认构造函数很容易实现:

  1. String::String() : data_(new StringBuf) { } 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇条款14:缓式优化,之二:(2) 下一篇条款25:将constructor和non-memb..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: