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;
}
相关推荐
小此方2 小时前
Re:思考·重建·记录 现代C++ C++11篇 (三) 深度解构:可变参数模板、类功能演进与 STL 的新版图
开发语言·c++·stl·c++11·现代c++
2401_892070983 小时前
八大排序算法
数据结构·c++·排序算法
无敌昊哥战神3 小时前
【算法与数据结构】深入浅出回溯算法:理论基础与核心模板(C/C++与Python三语解析)
c语言·数据结构·c++·笔记·python·算法
zore_c3 小时前
【C++】基础语法(命名空间、引用、缺省以及输入输出)
c语言·开发语言·数据结构·c++·经验分享·笔记
草莓熊Lotso3 小时前
Linux 线程深度剖析:线程 ID 本质、地址空间布局与 pthread 源码全解
android·linux·运维·服务器·数据库·c++
沐雪轻挽萤3 小时前
2. C++17新特性-结构化绑定 (Structured Bindings)
java·开发语言·c++
Robot_Nav3 小时前
ThetaStar全局规划算法纯C++控制器详解
开发语言·c++·lazy_theta_star
草莓熊Lotso4 小时前
MySQL 从入门到实战:视图特性 + 用户权限管理全解
linux·运维·服务器·数据库·c++·mysql
Q741_1474 小时前
每日一题 力扣 1848. 到目标元素的最小距离 模拟 C++题解
c++·算法·leetcode·模拟