COW(copy on write), SSO (small string optimization)浅析

有如下一段代码, 则输出结果是?



不一样的编译器可能会有不一样的结果,原因在于所使用的引用计数方法是COW还是SSO。比如VS上结果是false, false, false, 而老版本GCC上则是true, true, false,因trs为STL标准库对string的实现方法不同。


首先要明确一点,目前的实现中,不管哪种方式string的拷贝是深拷贝的。但是如果每次都是重新new一个对象,然后把数据复制过去,效率会很低。于是就有了俩种优化方案。


1. COW

思想是只有当修改string的时候再为这个修改操作重新生成一个拷贝,如果只是复制,那么就是共享这个数据。COW的实现机制是用一个引用计数,初始值是1,每次赋值的时候都会加1。当修改的时候,如果count > 1, 则会重新申请空间并复制,并且count--(因为正在修改的这个之前肯定是引用了这个数据),然后如果count = 0, 则释放原来内存。

需要注意的是,string会把[]跟at()操作认定为修改操作,因为很难定义到底是不是修改,所以一律当成了修改。比如以下的代码,string a = "hi", string b = a; b[0] = 'i';

则a= "hi", b="ii".


2. SSO

因为COW的弊端(除了上面提到的,还有其他的,比如多线程问题),新版本的编译器大多放弃了COW,而使用了SSO。SSO思想是立刻复制,同时有一个优化就是当字符串较短时,直接将其数据放到栈中,而不是在堆中动态申请内存,避免了申请空间的开销。


回到开头的例子,就不难理解为什么VS会输出false, false, false了,因为每次都是深拷贝。




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值