面试题答案
一键面试性能问题分析
- 时间复杂度:对
vector
进行随机访问操作的时间复杂度理论上为 $O(1)$,但由于CustomStruct
结构体中包含std::string
,而std::string
内部管理动态内存。当vector
进行扩容时,需要重新分配内存并复制所有元素,对于每个CustomStruct
中的std::string
成员,复制操作的时间复杂度不是常数时间,而是与字符串长度相关,平均时间复杂度可能接近线性,导致整体的随机访问操作在扩容时性能下降。
优化方案
- 方案一:使用
std::vector<std::unique_ptr<CustomStruct>>
- 实现方式:将
vector
存储的对象改为std::unique_ptr<CustomStruct>
,这样vector
中存储的是指针,在扩容时只需要复制指针,而不是整个CustomStruct
对象。 - 时间复杂度影响:扩容时复制操作的时间复杂度从与
CustomStruct
大小相关(特别是std::string
长度相关)变为常数时间(指针大小固定),使得整体随机访问操作在扩容场景下性能提升,随机访问的平均时间复杂度更接近理想的 $O(1)$。
- 实现方式:将
- 方案二:自定义内存管理
- 实现方式:自己实现一个内存池来管理
CustomStruct
对象的内存分配和释放,避免std::string
频繁的动态内存分配与释放。当vector
扩容时,从内存池中获取内存,减少动态内存分配的开销。 - 时间复杂度影响:减少了
std::string
动态内存分配与释放的时间开销,随机访问操作中涉及到内存分配相关的操作时间复杂度降低,整体随机访问操作的时间复杂度更接近理想的 $O(1)$。
- 实现方式:自己实现一个内存池来管理
- 方案三:将
std::string
替换为std::array<char, N>
- 实现方式:如果
name
的长度是有限且已知的,可以将std::string
替换为std::array<char, N>
,N
为最大可能的字符串长度。这样CustomStruct
的大小固定,vector
扩容时复制操作时间复杂度为常数(与结构体大小相关)。 - 时间复杂度影响:避免了
std::string
动态内存管理的开销,使得vector
扩容时复制操作时间复杂度为常数,随机访问操作的时间复杂度更稳定地保持在 $O(1)$。
- 实现方式:如果