C++ 标准库中性能较高的函数总结复习

1. 内存操作函数(最快)

std::memcpy / std::memmove

  • 性能特点 :直接操作内存块,通常由编译器优化为汇编指令(如 rep movsb),速度极快
  • 适用场景:POD类型(Plain Old Data)的批量复制
  • 性能对比:比循环赋值快 10-100 倍
cpp 复制代码
#include <cstring>

char src[1024] = {0};
char dst[1024];
std::memcpy(dst, src, 1024);  // 最快的内存复制方式

std::memset

  • 性能特点:快速填充内存块,同样是硬件级优化
  • 适用场景:初始化数组、清零操作
cpp 复制代码
#include <cstring>

char buffer[1024];
std::memset(buffer, 0, 1024);  // 比循环赋值快得多

2. 算法库(高度优化)

std::sort

  • 性能特点:通常实现为优化的 introsort(快速排序+堆排序+插入排序混合),是最快的通用排序算法
  • 性能对比:比大多数手写排序算法快 2-5 倍
cpp 复制代码
#include <algorithm>
#include <vector>

std::vector<int> v = {3, 1, 4, 1, 5, 9};
std::sort(v.begin(), v.end());  // O(n log n),高度优化

std::for_each

  • 性能特点:比手写循环更易被编译器优化,配合执行策略可并行化
  • C++17 并行版本std::for_each(std::execution::par, ...)
cpp 复制代码
#include <algorithm>
#include <vector>

int main() {
    std::vector<int> v(1000000);
    std::for_each(v.begin(), v.end(), [](int& x) { x *= 2; });
    return 0;
}

std::fill / std::fill_n

  • 性能特点 :对POD类型会优化为 memset,比循环赋值快
cpp 复制代码
#include <algorithm>
#include <vector>

std::vector<int> v(1000000);
std::fill(v.begin(), v.end(), 42);  // 快速填充

std::copy / std::copy_n

  • 性能特点 :对POD类型会优化为 memcpy
cpp 复制代码
#include <algorithm>
#include <vector>

std::vector<int> src(1000000);
std::vector<int> dst(1000000);
std::copy(src.begin(), src.end(), dst.begin());  // 内部可能用memcpy

3. 容器操作(零拷贝优化)

emplace_back / emplace

  • 性能特点:直接在容器中构造对象,避免拷贝/移动操作
  • 性能对比 :比 push_back 快 2-3 倍(对于复杂对象)
cpp 复制代码
#include <vector>
#include <string>

std::vector<std::string> v;
v.emplace_back("hello");  // 直接构造,比push_back("hello")更高效

reserve

  • 性能特点:预分配内存,避免多次重新分配和拷贝
  • 性能对比 :可使 push_back 循环快 10-100 倍
cpp 复制代码
#include <vector>

std::vector<int> v;
v.reserve(1000000);  // 预分配空间,关键优化!
for (int i = 0; i < 1000000; ++i) {
    v.push_back(i);
}

std::move

  • 性能特点:转移对象所有权,避免深拷贝
  • 适用场景:转移大型容器、字符串等
cpp 复制代码
#include <vector>
#include <utility>

std::vector<int> src(1000000);
std::vector<int> dst = std::move(src);  // O(1),只转移内部指针

4. 字符串操作

std::string::reserve

  • 性能特点:预分配内存,避免字符串拼接时的多次重新分配
cpp 复制代码
#include <string>

std::string s;
s.reserve(10000);  // 预分配空间
for (int i = 0; i < 1000; ++i) {
    s += "hello";
}

std::string_view (C++17)

  • 性能特点 :零拷贝字符串视图,避免不必要的 std::string 构造
  • 性能对比 :比传递 std::string 快 10-100 倍
cpp 复制代码
#include <string_view>

void process(std::string_view sv) {  // 零拷贝传递
    // 处理sv,不涉及内存分配
}

std::string s = "hello world";
process(s);  // 自动转换为string_view,无拷贝

5. 数学函数(硬件加速)

std::sqrt / std::sin / std::cos

  • 性能特点:通常直接映射为CPU浮点指令,硬件级加速
  • 注意:比手写近似算法慢,但精度更高
cpp 复制代码
#include <cmath>

double x = 2.0;
double y = std::sqrt(x);  // 硬件级加速

std::fma (C++11)

  • 性能特点:融合乘加操作(a*b+c),单条CPU指令完成
  • 性能对比:比分开的乘加操作快 2 倍,精度更高
cpp 复制代码
#include <cmath>

double a = 1.0, b = 2.0, c = 3.0;
double result = std::fma(a, b, c);  // 计算 a*b + c,单条指令

6. 类型转换(零开销)

std::move (C++11)

  • 性能特点:零开销类型转换,只改变值的类别
  • 本质 :只是一个 static_cast,不生成任何代码
cpp 复制代码
#include <utility>

T&& rvalue = std::move(lvalue);  // 零开销

std::forward (C++11)

  • 性能特点:完美转发,零开销
  • 适用场景:模板函数中保持参数的值类别
cpp 复制代码
#include <utility>

template<typename T>
void wrapper(T&& arg) {
    target(std::forward<T>(arg));  // 零开销完美转发
}

7. 时间操作(硬件级)

std::chrono::high_resolution_clock::now()

  • 性能特点:通常直接读取CPU时间戳计数器(TSC),纳秒级精度
  • 性能对比 :比 clock() 快 10-100 倍
cpp 复制代码
#include <chrono>

auto start = std::chrono::high_resolution_clock::now();
// 执行操作
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);

8. 代码实现比较

cpp 复制代码
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cstring>
#include <chrono>
#include <cmath>
#include <string_view>
#include <utility>
#include <random>

class Timer {
private:
    std::chrono::high_resolution_clock::time_point start_time;
    std::string name;
    int iterations;

public:
    Timer(const std::string& test_name, int iters) 
        : name(test_name), iterations(iters) {
        start_time = std::chrono::high_resolution_clock::now();
    }

    ~Timer() {
        auto end_time = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(
            end_time - start_time
        ).count();
        
        double avg_time_ns = static_cast<double>(duration) / iterations;
        std::printf("%-35s | 平均: %8.2f ns | 总耗时: %8.2f ms\n",
                   name.c_str(), avg_time_ns, duration / 1e6);
    }
};

template<typename T>
void do_not_optimize(T&& value) {
    asm volatile("" : : "r,m"(value) : "memory");
}

std::vector<int> generate_random_vector(int size) {
    std::vector<int> v(size);
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(1, 1000000);
    
    for (int& x : v) {
        x = dis(gen);
    }
    return v;
}

void test_memory_copy(int iterations, int size) {
    std::vector<char> src(size, 0x55);
    std::vector<char> dst(size);
    
    {
        Timer t("std::memcpy", iterations);
        for (int i = 0; i < iterations; ++i) {
            std::memcpy(dst.data(), src.data(), size);
            do_not_optimize(dst[0]);
        }
    }
    
    {
        Timer t("循环赋值 (char)", iterations);
        for (int i = 0; i < iterations; ++i) {
            for (int j = 0; j < size; ++j) {
                dst[j] = src[j];
            }
            do_not_optimize(dst[0]);
        }
    }
    
    {
        Timer t("std::copy", iterations);
        for (int i = 0; i < iterations; ++i) {
            std::copy(src.begin(), src.end(), dst.begin());
            do_not_optimize(dst[0]);
        }
    }
}

void test_memory_fill(int iterations, int size) {
    std::vector<char> buffer(size);
    
    {
        Timer t("std::memset", iterations);
        for (int i = 0; i < iterations; ++i) {
            std::memset(buffer.data(), 0, size);
            do_not_optimize(buffer[0]);
        }
    }
    
    {
        Timer t("std::fill", iterations);
        for (int i = 0; i < iterations; ++i) {
            std::fill(buffer.begin(), buffer.end(), 0);
            do_not_optimize(buffer[0]);
        }
    }
    
    {
        Timer t("循环赋值 (char)", iterations);
        for (int i = 0; i < iterations; ++i) {
            for (int j = 0; j < size; ++j) {
                buffer[j] = 0;
            }
            do_not_optimize(buffer[0]);
        }
    }
}

void test_sorting(int iterations, int size) {
    auto original = generate_random_vector(size);
    
    {
        std::vector<int> v = original;
        Timer t("std::sort", iterations);
        for (int i = 0; i < iterations; ++i) {
            std::sort(v.begin(), v.end());
            do_not_optimize(v[0]);
            std::shuffle(v.begin(), v.end(), std::mt19937(std::random_device{}()));
        }
    }
    
    {
        std::vector<int> v = original;
        Timer t("手写冒泡排序", iterations / 100); // 冒泡太慢,减少迭代次数
        for (int i = 0; i < iterations / 100; ++i) {
            for (int j = 0; j < size - 1; ++j) {
                for (int k = 0; k < size - j - 1; ++k) {
                    if (v[k] > v[k + 1]) {
                        std::swap(v[k], v[k + 1]);
                    }
                }
            }
            do_not_optimize(v[0]);
            std::shuffle(v.begin(), v.end(), std::mt19937(std::random_device{}()));
        }
    }
}

void test_container_insert(int iterations) {
    const int elements_per_iter = 1000;
    
    {
        Timer t("emplace_back (int)", iterations * elements_per_iter);
        for (int i = 0; i < iterations; ++i) {
            std::vector<int> v;
            v.reserve(elements_per_iter);
            for (int j = 0; j < elements_per_iter; ++j) {
                v.emplace_back(j);
            }
            do_not_optimize(v.size());
        }
    }
    
    {
        Timer t("push_back (int)", iterations * elements_per_iter);
        for (int i = 0; i < iterations; ++i) {
            std::vector<int> v;
            v.reserve(elements_per_iter);
            for (int j = 0; j < elements_per_iter; ++j) {
                v.push_back(j);
            }
            do_not_optimize(v.size());
        }
    }
    
    {
        Timer t("emplace_back (std::string)", iterations * elements_per_iter);
        for (int i = 0; i < iterations; ++i) {
            std::vector<std::string> v;
            v.reserve(elements_per_iter);
            for (int j = 0; j < elements_per_iter; ++j) {
                v.emplace_back("hello" + std::to_string(j));
            }
            do_not_optimize(v.size());
        }
    }
    
    {
        Timer t("push_back (std::string)", iterations * elements_per_iter);
        for (int i = 0; i < iterations; ++i) {
            std::vector<std::string> v;
            v.reserve(elements_per_iter);
            for (int j = 0; j < elements_per_iter; ++j) {
                v.push_back("hello" + std::to_string(j));
            }
            do_not_optimize(v.size());
        }
    }
}

void test_reserve(int iterations, int size) {
    {
        Timer t("有 reserve 的 push_back", iterations * size);
        for (int i = 0; i < iterations; ++i) {
            std::vector<int> v;
            v.reserve(size);
            for (int j = 0; j < size; ++j) {
                v.push_back(j);
            }
            do_not_optimize(v.size());
        }
    }
    
    {
        Timer t("无 reserve 的 push_back", iterations * size);
        for (int i = 0; i < iterations; ++i) {
            std::vector<int> v;
            for (int j = 0; j < size; ++j) {
                v.push_back(j);
            }
            do_not_optimize(v.size());
        }
    }
}

void test_string_view(int iterations) {
    std::string long_string(1000, 'a');
    
    auto process_string = [](const std::string& s) {
        return s.size();
    };
    
    auto process_string_view = [](std::string_view sv) {
        return sv.size();
    };
    
    {
        Timer t("传递 std::string", iterations);
        for (int i = 0; i < iterations; ++i) {
            auto result = process_string(long_string);
            do_not_optimize(result);
        }
    }
    
    {
        Timer t("传递 std::string_view", iterations);
        for (int i = 0; i < iterations; ++i) {
            auto result = process_string_view(long_string);
            do_not_optimize(result);
        }
    }
}

void test_math_functions(int iterations) {
    std::vector<double> a(iterations);
    std::vector<double> b(iterations);
    std::vector<double> c(iterations);
    
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<> dis(0.0, 1.0);
    
    for (int i = 0; i < iterations; ++i) {
        a[i] = dis(gen);
        b[i] = dis(gen);
        c[i] = dis(gen);
    }
    
    {
        Timer t("分开的乘加 (a*b+c)", iterations);
        double result = 0.0;
        for (int i = 0; i < iterations; ++i) {
            result += a[i] * b[i] + c[i];
        }
        do_not_optimize(result);
    }
    
    {
        Timer t("std::fma (a*b+c)", iterations);
        double result = 0.0;
        for (int i = 0; i < iterations; ++i) {
            result += std::fma(a[i], b[i], c[i]);
        }
        do_not_optimize(result);
    }
}

void test_move_semantics(int iterations, int size) {
    {
        Timer t("深拷贝 std::vector", iterations);
        for (int i = 0; i < iterations; ++i) {
            std::vector<int> src(size, 42);
            std::vector<int> dst = src; // 深拷贝
            do_not_optimize(dst.size());
        }
    }
    
    {
        Timer t("std::move 转移所有权", iterations);
        for (int i = 0; i < iterations; ++i) {
            std::vector<int> src(size, 42);
            std::vector<int> dst = std::move(src); // 移动,O(1)
            do_not_optimize(dst.size());
        }
    }
}

int main() {
    std::cout << "=============================================" << std::endl;
    std::cout << "C++ 标准函数性能对比测试" << std::endl;
    std::cout << "编译选项: -O3" << std::endl;
    std::cout << "=============================================" << std::endl << std::endl;
    
    const int ITERATIONS = 10000;
    const int SMALL_SIZE = 1024;
    const int MEDIUM_SIZE = 10000;
    const int LARGE_SIZE = 100000;
    
    std::cout << "=== 内存操作测试 (1KB 数据) ===" << std::endl;
    test_memory_copy(ITERATIONS, SMALL_SIZE);
    std::cout << std::endl;
    
    std::cout << "=== 内存填充测试 (1KB 数据) ===" << std::endl;
    test_memory_fill(ITERATIONS, SMALL_SIZE);
    std::cout << std::endl;
    
    std::cout << "=== 排序算法测试 (10000 个元素) ===" << std::endl;
    test_sorting(ITERATIONS / 10, MEDIUM_SIZE);
    std::cout << std::endl;
    
    std::cout << "=== 容器插入测试 ===" << std::endl;
    test_container_insert(ITERATIONS / 10);
    std::cout << std::endl;
    
    std::cout << "=== reserve 预分配测试 (10000 个元素) ===" << std::endl;
    test_reserve(ITERATIONS / 10, MEDIUM_SIZE);
    std::cout << std::endl;
    
    std::cout << "=== 字符串传递测试 ===" << std::endl;
    test_string_view(ITERATIONS * 10);
    std::cout << std::endl;
    
    std::cout << "=== 数学函数测试 ===" << std::endl;
    test_math_functions(ITERATIONS * 100);
    std::cout << std::endl;
    
    std::cout << "=== 移动语义测试 (100000 个元素) ===" << std::endl;
    test_move_semantics(ITERATIONS / 100, LARGE_SIZE);
    std::cout << std::endl;
    
    std::cout << "=============================================" << std::endl;
    std::cout << "测试完成!" << std::endl;
    std::cout << "=============================================" << std::endl;
    
    return 0;
}
相关推荐
汉克老师1 天前
GESP2025年3月认证C++五级( 第三部分编程题(1、平均分配))
c++·算法·贪心算法·排序·gesp5级·gesp五级
智者知已应修善业1 天前
【51单片机2个按键控制流水灯运行与暂停】2023-9-6
c++·经验分享·笔记·算法·51单片机
云泽8081 天前
C++11 核心特性全解:列表初始化、右值引用与移动语义实战
开发语言·c++
AI进化营-智能译站1 天前
ROS2 C++开发系列12-用多态与虚函数构建可扩展的ROS2机器人行为模块
开发语言·c++·ai·机器人
Morwit1 天前
QML组件之间的通信方案(暴露子组件)
c++·qt·职场和发展
qeen871 天前
【数据结构】建堆的时间复杂度讨论与TOP-K问题
c语言·数据结构·c++·学习·
图码1 天前
如何用多种方法判断字符串是否为回文?
开发语言·数据结构·c++·算法·阿里云·线性回归·数字雕刻
handler011 天前
Linux 内核剖析:进程优先级、上下文切换与 O(1) 调度算法
linux·运维·c语言·开发语言·c++·笔记·算法
zhouwy1131 天前
Linux进程与线程编程详解
linux·c++
A7bert7771 天前
【YOLOv8pose部署至RDK X5】模型训练→转换bin→Sunrise 5部署
c++·python·深度学习·yolo·目标检测