Skip to content

C++ 性能优化

概述

性能优化是C++编程的重要方面。本章介绍内存管理、算法优化、编译器优化、性能测量等关键技术,帮助开发者写出高效的C++程序。

📊 性能测量

基准测试

cpp
#include <iostream>
#include <chrono>
#include <vector>
#include <algorithm>

class Timer {
private:
    std::chrono::high_resolution_clock::time_point start_;
    std::string name_;
    
public:
    Timer(const std::string& name) : name_(name) {
        start_ = std::chrono::high_resolution_clock::now();
    }
    
    ~Timer() {
        auto end = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start_);
        std::cout << name_ << " 耗时: " << duration.count() << " 微秒" << std::endl;
    }
};

void memoryAccessTest() {
    const size_t SIZE = 1024 * 1024;
    std::vector<int> data(SIZE, 1);
    
    // 顺序访问
    {
        Timer timer("顺序访问");
        int sum = 0;
        for (size_t i = 0; i < SIZE; ++i) {
            sum += data[i];
        }
    }
    
    // 跳跃访问
    {
        Timer timer("跳跃访问");
        int sum = 0;
        for (size_t i = 0; i < SIZE; i += 16) {
            sum += data[i];
        }
    }
}

🧠 内存优化

对象池模式

cpp
#include <vector>
#include <memory>

template<typename T>
class ObjectPool {
private:
    std::vector<std::unique_ptr<T>> pool_;
    std::vector<T*> available_;
    
public:
    T* acquire() {
        if (available_.empty()) {
            pool_.push_back(std::make_unique<T>());
            return pool_.back().get();
        }
        T* obj = available_.back();
        available_.pop_back();
        return obj;
    }
    
    void release(T* obj) {
        available_.push_back(obj);
    }
};

// 使用示例
void objectPoolDemo() {
    struct ExpensiveObject {
        std::vector<int> data;
        ExpensiveObject() : data(1000, 42) {}
    };
    
    ObjectPool<ExpensiveObject> pool;
    
    // 对象池版本
    {
        Timer timer("对象池");
        for (int i = 0; i < 1000; ++i) {
            auto* obj = pool.acquire();
            // 使用对象
            pool.release(obj);
        }
    }
    
    // 直接创建版本
    {
        Timer timer("直接创建");
        for (int i = 0; i < 1000; ++i) {
            auto obj = std::make_unique<ExpensiveObject>();
            // 使用对象
        }
    }
}

内存池分配器

cpp
class MemoryPool {
private:
    char* memory_;
    size_t block_size_;
    std::vector<void*> free_blocks_;
    
public:
    MemoryPool(size_t block_size, size_t num_blocks) 
        : block_size_(block_size) {
        memory_ = new char[block_size * num_blocks];
        
        for (size_t i = 0; i < num_blocks; ++i) {
            free_blocks_.push_back(memory_ + i * block_size);
        }
    }
    
    ~MemoryPool() {
        delete[] memory_;
    }
    
    void* allocate() {
        if (free_blocks_.empty()) return nullptr;
        void* block = free_blocks_.back();
        free_blocks_.pop_back();
        return block;
    }
    
    void deallocate(void* ptr) {
        free_blocks_.push_back(ptr);
    }
};

⚡ 算法优化

容器选择

cpp
#include <set>
#include <unordered_set>
#include <vector>

void containerComparison() {
    const size_t SIZE = 100000;
    const int SEARCH_VALUE = SIZE / 2;
    
    std::vector<int> vec(SIZE);
    std::iota(vec.begin(), vec.end(), 0);
    
    std::set<int> ordered_set(vec.begin(), vec.end());
    std::unordered_set<int> hash_set(vec.begin(), vec.end());
    
    // 线性查找
    {
        Timer timer("vector线性查找");
        auto it = std::find(vec.begin(), vec.end(), SEARCH_VALUE);
    }
    
    // 二分查找
    {
        Timer timer("vector二分查找");
        bool found = std::binary_search(vec.begin(), vec.end(), SEARCH_VALUE);
    }
    
    // 有序集合查找
    {
        Timer timer("set查找");
        auto it = ordered_set.find(SEARCH_VALUE);
    }
    
    // 哈希表查找
    {
        Timer timer("unordered_set查找");
        auto it = hash_set.find(SEARCH_VALUE);
    }
}

循环优化

cpp
void loopOptimization() {
    const size_t SIZE = 1000;
    std::vector<std::vector<int>> matrix(SIZE, std::vector<int>(SIZE, 1));
    
    // 按行访问(缓存友好)
    {
        Timer timer("按行访问");
        long long sum = 0;
        for (size_t i = 0; i < SIZE; ++i) {
            for (size_t j = 0; j < SIZE; ++j) {
                sum += matrix[i][j];
            }
        }
    }
    
    // 按列访问(缓存不友好)
    {
        Timer timer("按列访问");
        long long sum = 0;
        for (size_t j = 0; j < SIZE; ++j) {
            for (size_t i = 0; i < SIZE; ++i) {
                sum += matrix[i][j];
            }
        }
    }
    
    // 循环展开
    {
        Timer timer("循环展开");
        long long sum = 0;
        for (size_t i = 0; i < SIZE; ++i) {
            size_t j;
            for (j = 0; j + 4 <= SIZE; j += 4) {
                sum += matrix[i][j] + matrix[i][j+1] + 
                       matrix[i][j+2] + matrix[i][j+3];
            }
            for (; j < SIZE; ++j) {
                sum += matrix[i][j];
            }
        }
    }
}

🔧 编译器优化

内联和常量优化

cpp
// 内联函数
inline int fastAdd(int a, int b) {
    return a + b;
}

// 常量表达式
constexpr int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

void compilerOptimizations() {
    const int ITERATIONS = 10000000;
    
    // 函数调用
    {
        Timer timer("函数调用");
        int sum = 0;
        for (int i = 0; i < ITERATIONS; ++i) {
            sum = fastAdd(sum, i);
        }
    }
    
    // 直接计算
    {
        Timer timer("直接计算");
        int sum = 0;
        for (int i = 0; i < ITERATIONS; ++i) {
            sum += i;
        }
    }
    
    // 编译时计算
    constexpr int result = factorial(10);
    std::cout << "编译时计算结果: " << result << std::endl;
}

分支预测优化

cpp
void branchPrediction() {
    const size_t SIZE = 1000000;
    std::vector<int> data(SIZE);
    
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(0, 100);
    for (auto& val : data) {
        val = dis(gen);
    }
    
    const int THRESHOLD = 50;
    
    // 随机数据(分支难预测)
    {
        Timer timer("分支不可预测");
        int count = 0;
        for (int value : data) {
            if (value > THRESHOLD) {
                count++;
            }
        }
    }
    
    // 排序后(分支可预测)
    std::sort(data.begin(), data.end());
    {
        Timer timer("分支可预测");
        int count = 0;
        for (int value : data) {
            if (value > THRESHOLD) {
                count++;
            }
        }
    }
    
    // 无分支版本
    {
        Timer timer("无分支版本");
        int count = 0;
        for (int value : data) {
            count += (value > THRESHOLD);
        }
    }
}

🚀 高级优化

并行算法

cpp
#include <execution>
#include <numeric>

void parallelOptimization() {
    const size_t SIZE = 10000000;
    std::vector<int> data(SIZE);
    std::iota(data.begin(), data.end(), 1);
    
    // 串行求和
    {
        Timer timer("串行求和");
        long long sum = std::accumulate(data.begin(), data.end(), 0LL);
    }
    
    // 并行求和(C++17)
    #ifdef __cpp_lib_parallel_algorithm
    {
        Timer timer("并行求和");
        long long sum = std::reduce(std::execution::par, data.begin(), data.end(), 0LL);
    }
    #endif
}

缓存优化

cpp
// 数组结构 vs 结构数组
struct Point3D_AoS {
    float x, y, z;
};

struct Points3D_SoA {
    std::vector<float> x, y, z;
    Points3D_SoA(size_t size) : x(size), y(size), z(size) {}
};

void cacheOptimization() {
    const size_t SIZE = 1000000;
    
    std::vector<Point3D_AoS> aos_points(SIZE);
    Points3D_SoA soa_points(SIZE);
    
    // AoS访问(可能缓存不友好)
    {
        Timer timer("AoS访问");
        float sum = 0;
        for (const auto& point : aos_points) {
            sum += point.x;
        }
    }
    
    // SoA访问(缓存友好)
    {
        Timer timer("SoA访问");
        float sum = 0;
        for (float x : soa_points.x) {
            sum += x;
        }
    }
}

演示程序

cpp
int main() {
    std::cout << "=== C++ 性能优化演示 ===" << std::endl;
    
    std::cout << "\n1. 内存访问模式:" << std::endl;
    memoryAccessTest();
    
    std::cout << "\n2. 对象池优化:" << std::endl;
    objectPoolDemo();
    
    std::cout << "\n3. 容器选择:" << std::endl;
    containerComparison();
    
    std::cout << "\n4. 循环优化:" << std::endl;
    loopOptimization();
    
    std::cout << "\n5. 编译器优化:" << std::endl;
    compilerOptimizations();
    
    std::cout << "\n6. 分支预测:" << std::endl;
    branchPrediction();
    
    std::cout << "\n7. 并行优化:" << std::endl;
    parallelOptimization();
    
    std::cout << "\n8. 缓存优化:" << std::endl;
    cacheOptimization();
    
    return 0;
}

总结

优化策略

  • 测量优先: 先测量再优化
  • 算法为王: 选择正确的算法和数据结构
  • 内存意识: 考虑缓存友好性和内存访问模式
  • 编译器配合: 利用编译器优化特性

性能要点

技术影响适用场景
缓存优化大数据处理
内存池频繁分配
并行算法CPU密集型
分支预测条件密集型

最佳实践

  • 选择合适的容器和算法
  • 考虑内存布局和访问模式
  • 利用编译器优化选项
  • 在关键路径上进行细致优化
  • 平衡代码可读性和性能

性能优化需要深入理解计算机体系结构和编译器工作原理,是高级C++开发的重要技能。

本站内容仅供学习和研究使用。