高性能std::string实现分析
1. 字符串存储策略
1.1 小字符串优化(SSO)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class string { private: static const size_t SSO_SIZE = 15; union { struct { char* data; size_t size; size_t capacity; } heap; struct { char data[SSO_SIZE + 1]; unsigned char size; } stack; } storage; bool is_sso() const { return storage.stack.size < SSO_SIZE; } };
|
优势:
- 避免小字符串的堆分配
- 减少内存碎片
- 提高缓存局部性
1.2 中长字符串处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class string { void grow(size_t new_capacity) { size_t new_size = std::max( new_capacity, capacity() * 2 ); char* new_data = allocate(new_size); memcpy(new_data, data(), size()); deallocate(data()); storage.heap.data = new_data; storage.heap.capacity = new_size; } };
|
2. 引用计数优化
2.1 共享字符串实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class string { private: struct SharedData { std::atomic<size_t> ref_count; size_t size; size_t capacity; char data[1]; }; SharedData* shared; void add_ref() { if (shared) { shared->ref_count.fetch_add(1, std::memory_order_relaxed); } } void release() { if (shared && shared->ref_count.fetch_sub(1, std::memory_order_acq_rel) == 1) { deallocate(shared); } } };
|
2.2 写时复制(COW)
1 2 3 4 5 6 7 8 9 10 11
| class string { void ensure_unique() { if (shared && shared->ref_count.load(std::memory_order_acquire) > 1) { SharedData* new_data = allocate(size()); memcpy(new_data->data, shared->data, size()); release(); shared = new_data; shared->ref_count.store(1, std::memory_order_relaxed); } } };
|
3. 字面量优化
3.1 字符串字面量处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class string { template<size_t N> string(const char (&str)[N]) { if (N <= SSO_SIZE) { memcpy(storage.stack.data, str, N); storage.stack.size = N; } else { storage.heap.data = allocate(N); memcpy(storage.heap.data, str, N); storage.heap.size = N; storage.heap.capacity = N; } } };
|
3.2 字符串视图
1 2 3 4 5 6 7 8 9
| class string_view { const char* data_; size_t size_; public: string_view(const string& str) : data_(str.data()), size_(str.size()) {} };
|
4. 内存管理优化
4.1 内存池
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class StringPool { static const size_t BLOCK_SIZE = 4096; struct Block { char* data; size_t used; Block* next; }; Block* current_block; char* allocate(size_t size) { if (current_block->used + size > BLOCK_SIZE) { allocate_new_block(); } char* ptr = current_block->data + current_block->used; current_block->used += size; return ptr; } };
|
4.2 对齐优化
1 2 3 4 5 6 7 8
| class string { static const size_t ALIGNMENT = 16; char* allocate(size_t size) { size_t aligned_size = (size + ALIGNMENT - 1) & ~(ALIGNMENT - 1); return static_cast<char*>(aligned_alloc(ALIGNMENT, aligned_size)); } };
|
5. 性能优化技巧
5.1 移动语义
1 2 3 4 5 6 7 8 9 10 11 12 13
| class string { string(string&& other) noexcept { if (other.is_sso()) { memcpy(storage.stack.data, other.storage.stack.data, other.size()); storage.stack.size = other.storage.stack.size; } else { storage.heap = other.storage.heap; other.storage.heap.data = nullptr; other.storage.heap.size = 0; other.storage.heap.capacity = 0; } } };
|
5.2 预留空间
1 2 3 4 5 6 7 8 9 10
| class string { void reserve(size_t new_capacity) { if (new_capacity > capacity()) { if (is_sso() && new_capacity <= SSO_SIZE) { return; } grow(new_capacity); } } };
|
6. 线程安全考虑
6.1 引用计数原子操作
1 2 3 4 5 6 7 8 9 10 11 12
| class string { struct SharedData { std::atomic<size_t> ref_count; }; void add_ref() { if (shared) { shared->ref_count.fetch_add(1, std::memory_order_relaxed); } } };
|
6.2 写时复制线程安全
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class string { void ensure_unique() { if (shared) { size_t refs = shared->ref_count.load(std::memory_order_acquire); if (refs > 1) { SharedData* new_data = allocate(size()); memcpy(new_data->data, shared->data, size()); release(); shared = new_data; shared->ref_count.store(1, std::memory_order_relaxed); } } } };
|
7. 性能测试指标
7.1 内存使用
- 小字符串(<16字节):栈存储,零堆分配
- 中字符串(16-64字节):单次堆分配
- 大字符串(>64字节):多次堆分配
7.2 操作性能
- 构造/析构:O(1) 小字符串,O(n) 大字符串
- 复制:O(1) 引用计数,O(n) 写时复制
- 修改:O(1) 小字符串,O(n) 大字符串
8. 总结
高性能std::string实现需要综合考虑多个方面:
- 小字符串优化(SSO)减少堆分配
- 引用计数优化内存使用
- 字面量处理提高构造效率
- 内存管理优化减少碎片
- 移动语义提升性能
- 线程安全保证正确性
通过合理使用这些技术,可以在保证功能正确性的同时,显著提升字符串操作的性能。