#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;
}