C++优化 —— 字符串优化

本文探讨了C++中字符串性能优化的各种方法,包括使用内置mutating函数避免临时字符串,通过预留空间减少内存再分配,利用const引用来消除传参时的复制,以及通过迭代器消除解引用操作。通过实例分析,展示了这些优化如何显著提升代码效率。
摘要由CSDN通过智能技术生成

这篇博客介绍了C++中常用的用于优化C++性能的手法。


背景

最近开始读Optimized C++,因此也会开始记录一些读书笔记。然后呢……由于入职鹅厂,考虑到项目保密这一块,因此以后的UE4相关的博客可能会少更一些,就算要更估计也是只会和个人研究相关了……

C++的字符串与性能

字符串的动态分配

相比起C的函数(例如strcat()strcpy())是操作在固定长度的字符数组上来说,C++的字符串使用起来更加方便 —— 这是因为它可以在需要的时候自动变长。为了实现这个效果,C++的字符串是动态分配的,而动态分配则是非常昂贵的。

std::vector类似,std::string采用的是当字符串变长时,另外分出一块更大的空间来用于储存这个字符串。有一些实现方法是直接将当前的字符串长度翻倍。这样的好处在于可以比较好的应对字符串频繁变动的情况,而坏处在于有可能会浪费一部分内存空间。

字符串是值类型

在对字符串进行赋值或者其他操作时,字符串往往表现为值类型(Value Object)。关于Value Object与Entities的区别这里就不展开讲,可以参考这篇博客

例如说,在进行字符串连接的操作(concatenate):s1 = s2 + s3 + s4时。由于字符串是值类型的,因此首先s2 + s3的结果会被作为一个单独的值类型保存在内存中,而后与s4进行连接时,会将结果暂存到另一个动态分配的内存中,这个值取代原来s1的值。最后,内存管理器会把原来s1与之前的那些暂存的值给free掉。

这就意味着对于调用了很多次的内存管理函数,对于性能会出现影响。

字符串会导致很多复制操作

由于字符串是值类型,因此你在修改一个字符串的时候不可以影响到另一个字符串。但是的的确确的,我们有时候需要对一个字符串进行修改。因此对每个字符串,它们都需要表现得像有一个对应内容的私人备份一样。

为了解决这种问题,比较常用的方法就是写时复制(”Copy on Write”,也成为COW),也就是说只在被创建、赋值或者作为变量被传入函数的时候复制一份。

在写时复制的情况下,字符串们可以通过引用计数的方式共享那些被动态分配的内存。当一个字符串被赋值为其中一个已经被记录下来的字符串时,此时只复制一个指针,并且计数+1.当字符串要进行改动或者其他操作时,会先检测这个字符串是否只有一个指针记录,如果有多个指针指向这个字符串,那么需要额外开辟内存,并且复制一份这个字符串,然后再进行处理。

因此,当你的string是使用COW的方式实现的话,赋值和传参操作性能会比较好,但是当字符串被多个指针指向的时候,所有的non-const针对可能进行修改字符串的函数都是比较贵的。

到了C++11,字符串的复制性能消耗或多或少的会被右值引用以及std::Move操作又花了不少。如果一个函数是将一个右值引用作为参数的话,那么此时的字符串可以直接进行一次指针复制即可,就节省了一次复制操作。<

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值