总结了一些关于性能方面的知识/经验,跟大家分析下。
欢迎大家在评论进行补充(我会按照补充添加)。
希望大家点赞收藏
1. 避免频繁内存申请(避免频繁系统函数调用)
- 系统调用通常涉及到与操作系统内核的交互
- 操作通常涉及资源调度、复杂的数据结构和算法、异常校验
- 频繁内存分配会造成内存碎片,导致操作系统可能需要耗时寻找足够大的连续内存块
- 系统调用本身是线程安全的,操作系统内核会在内部使用各种技术和算法来确保系统调用的正确性和线程安全性。
建议: 在需要频繁调用场景下,多了解需使用的系统函数调用内部实现原理,选择一些更优的方案替换系统调用,或一些策略减少系统调用.
2. 避免不必要的内存访问
(1) 尽量Cache命中
- 遵循局部性原理,即尽量让数据在物理内存上连续存储,以减少缓存未命中的次数。这可以通过适当的数组和结构体布局来实现。
- 尽量减少跨页或跨块的数据访问,因为这可能导致更高的内存访问延迟
- 常用局部变量加上register关键字
建议编译器尽可能地把变量存放在寄存器中,以加快其访问速度。
(2) 使用数据缓存
-
如果某些数据被频繁访问,考虑将它们缓存在更快的存储介质中,如CPU缓存或寄存器
-
在某些情况下,使用内存池或对象池可以避免频繁的内存分配和释放,从而提高性能
概念1: 存储金字塔
** 越靠近 CPU 速度越快,容量越小,价格越贵
** 每一种存储器设备只和它相邻的存储设备打交道 比如,CPU Cache 是从内存里加载而来的,或者需要写回内存,并不会直接写回数据到硬盘,也不会直接从硬盘加载数据到 CPU Cache 中,而是先加载到内存,再从内存加载到 Cache 中。概念2: 高速缓存-Cache
** CPU和内存之间速度严重不匹配的问题,在CPU和内存之间设计了高速缓存,即Cache。
CPU读取数据时,会在L1、L2、L3Cache中逐级查找,如果找到,就从Cache直接读取,找不到再从内存读取,并且把数据存放到Cache中,以便提高下次访问的效率。
在这个过程中,如果在Cache中找到所需数据,称为Cache命中(Cache Hit), 找不到称为Cache未命中(Cache Miss)。
L1 Cache命中的时候,读取数据最快,性能最好,而当L1、L2、L3 Cache全部未命中时,就必须要直接从内存中读取数据,性能最差概念3: 局部性原理
** 时间局部性。如果一个数据在某个时间点被CPU访问了,那么在接下来很短的一段时间内,这个数据很有可能会再次被CPU访问到。
** 空间局部性。如果一个数据在某个时间点被CPU访问了,那么与这个数据临近的其他数据,很有可能也会很快被CPU访问到。概念4: 缓存行-Cache Line
** 根据 局部性原理 如果一个数据被CPU访问了,那么这个数据相邻的其他数据也很快会被访问到。因此,为了提高内存数据的读取效率,并且最大化利用CPU资源,数据在Cache和内存之间传输时,不是一个字节一个字节进行传输的,而是以缓存行(Cache Line)为单位进行传输的。
(3) 数据结构优化
设计/选择 合适的数据结构和算法,避免不必要的数据复制和遍历。选择合适的数据结构可以减少内存访问次数和数据移动操作。
(4) 尽量确保内存对齐
大多数现代处理器在访问未对齐的内存时,性能会下降。这是因为处理器通常一次从内