C++性能优化入门


编写正常运行的程序很容易,但一旦数据量大起来,对代码的性能就需要认真考虑了。对于服务器来说,如果客户端一次访问,就需要话费几百毫秒,那么一旦每秒的访问次数躲起来,前端就会造成很明显的延迟。严重影响用户体验。最近做后端服务也遇到了一些需要优化的问题。
性能优化的前提是良好的构架设计:如果架构本身的设计就存在问题,在怎么优化也所能提升的空间也是很小。根据二八原则,大部分性能应该消耗在很少的地方,所以优化的关注点就在于那20%最耗时的代码块,解决了这个问题,整体性能就会有很大的提升。
代码层面的优化一般涉及到一下方面:

1.并发模型的选择

对于不同的功能需要用不同的并发模型,适合单线程还是多线程,以及线程池这些都会影响到性能,对于服务器,模块是io密集型还是计算密集型。例如如果一次请求是需要做很多的计算,那么用线程池是合理的能够简化编程,但是如果一次请求主要时间是等待io,那么线程池是无法提升吞吐量的。

2.数据的存储

容器的选择

数据对象的存储方式取决于对数据的使用方式,就拿C++容器来说,如果要存储物品信息,一般系统中更多的是根据物品id来获取物品信息,那么久需要用key-value来存取,但map是红黑树,unorder_map是哈希表,哈希表的查询时间是O(1),而对于map,插入、删除都是O(logN),最坏和平均都是。

存取方式

是存指针还是存数据,这个需要根据具体问题,具体分心。

3.算法

算法的存在就是为了高效的解决一些复杂问题,以减少时间或者空间复杂度。一个排序就有很多种选择,冒泡,选择,快排,堆排序,堆排序,归并等。一般来说快排的整体效率比较高,那是针对于基本无序的序列,如果只是后来的元素无序,前面基本有序,这时候简单的使用快排就会造成降低性能。

4.代码质量

使用引用

在C++中尽量采用引用传递或者指针传递,这样不会产生参数拷贝,如果传入参数是一个复杂的数据结构,就能明显的提升性能。同理获取数据时也要用引用。

减少副作用

例如C++是不进行边界检查的,对于map的获取value,如果该key不在map中,map会插入一个key,value为默认值

    std::map<int,int> i_map;
    int value = i_map[123];

map是红黑树实现的,红黑树最终是一平衡树,这个插入操作会导致原来的树不平衡,内部就需要翻转达到平衡,这就会造成性能消耗。

同一变量的多次获取:

std::vector<int> v_int;
...
for (int i = 0; i < v_int.size(); i++)

怎么写出高质量的C++代码,推荐一本书 《高质量C++/C编程指南》。

同步锁

服务器编程会涉及到多线程,一旦涉及多线程,多线程中很多涉及到竞争资源的非原子操作都需要进行加锁,加锁的方式有很多种有信号量,互斥器,条件变量,读写锁。绝大多数情况使用互斥器就可以足够实现大多数功能,而且相对于其他锁性能影响较小。但在使用mutex时也需要注意。

  • 锁的范围:只在需要同步的操作前后加锁和解锁,避免造成其他线程的无效的等待,造成性能损失。
  • 尽量将操作划分,对于多种无前后依赖的临界资源,用多个互斥器
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值