论GCC函数和标准库函数速度对比
2026-08-10 14:52:59
发布于:浙江
众所周知,在STL标准库中的许多函数都有__builtin_的GCC平替,今天我们就来测试一下他们两个之间的速度差异。
例子1:__builtin_pow VS pow
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double lf;
lf e=exp(1);
// ============ __builtin_pow 实现 ============
namespace math {
__attribute__((always_inline))
inline lf pow(lf a, lf b) {
return __builtin_pow(a,b);
}
}
// ============ 测试工具 ============
class Timer {
chrono::high_resolution_clock::time_point start;
public:
Timer() : start(chrono::high_resolution_clock::now()) {}
double elapsed_ms() {
auto end = chrono::high_resolution_clock::now();
return chrono::duration<double, milli>(end - start).count();
}
double elapsed_ns() {
auto end = chrono::high_resolution_clock::now();
return chrono::duration<double, nano>(end - start).count();
}
};
// ============ 测试场景 ============
struct TestCase {
string name;
double a_start, a_end;
double b_start, b_end;
int count;
};
// ============ 运行对比 ============
void run_benchmark(const TestCase& tc) {
cout << "\n┌─────────────────────────────────────────────────────────────────┐" << endl;
cout << "│ 测试: " << setw(60) << left << tc.name << "│" << endl;
cout << "├─────────────────────────────────────────────────────────────────┤" << endl;
// 生成测试数据
vector<double> bases(tc.count), exponents(tc.count);
random_device rd;
mt19937 gen(rd());
uniform_real_distribution<double> dist_a(tc.a_start, tc.a_end);
uniform_real_distribution<double> dist_b(tc.b_start, tc.b_end);
for (int i = 0; i < tc.count; i++) {
bases[i] = dist_a(gen);
exponents[i] = dist_b(gen);
}
vector<double> result_math(tc.count), result_std(tc.count);
// 预热
volatile double dummy = 0;
for (int i = 0; i < 100; i++) {
dummy += math::pow(bases[i % tc.count], exponents[i % tc.count]);
dummy += std::pow(bases[i % tc.count], exponents[i % tc.count]);
}
// 测试 math::pow
Timer t1;
for (int i = 0; i < tc.count; i++) {
result_math[i] = math::pow(bases[i], exponents[i]);
}
double time_math = t1.elapsed_ms();
// 测试 std::pow
Timer t2;
for (int i = 0; i < tc.count; i++) {
result_std[i] = std::pow(bases[i], exponents[i]);
}
double time_std = t2.elapsed_ms();
// 验证正确性(允许微小误差)
double max_error = 0;
double avg_error = 0;
int errors = 0;
for (int i = 0; i < tc.count; i++) {
double err = fabs(result_math[i] - result_std[i]);
if (err > 1e-9) {
errors++;
max_error = max(max_error, err);
avg_error += err;
}
}
if (errors > 0) avg_error /= errors;
// 输出结果
cout << "│ " << setw(10) << "实现"
<< setw(15) << "总时间(ms)"
<< setw(15) << "平均(ns)"
<< setw(15) << "吞吐(M ops/s)"
<< "│" << endl;
cout << "├─────────────────────────────────────────────────────────────────┤" << endl;
cout << "│ " << setw(10) << left << "math::pow"
<< setw(15) << right << fixed << setprecision(3) << time_math
<< setw(15) << fixed << setprecision(1) << (time_math * 1e6 / tc.count)
<< setw(15) << fixed << setprecision(2) << (tc.count / time_math / 1000.0)
<< " │" << endl;
cout << "│ " << setw(10) << left << "std::pow"
<< setw(15) << right << fixed << setprecision(3) << time_std
<< setw(15) << fixed << setprecision(1) << (time_std * 1e6 / tc.count)
<< setw(15) << fixed << setprecision(2) << (tc.count / time_std / 1000.0)
<< " │" << endl;
cout << "├─────────────────────────────────────────────────────────────────┤" << endl;
double speedup = time_std / time_math;
cout << "│ 🚀 加速比: " << setw(10) << fixed << setprecision(2) << speedup << "x"
<< " (" << (speedup > 1 ? "math::pow更快" : "std::pow更快") << ")"
<< setw(20) << "│" << endl;
if (errors > 0) {
cout << "│ ⚠️ 精度误差: 最大=" << scientific << setprecision(2) << max_error
<< ", 平均=" << avg_error << " (" << errors << "/" << tc.count << ")"
<< setw(10) << "│" << endl;
} else {
cout << "│ ✅ 精度验证: 完全匹配 (误差 < 1e-9)" << setw(30) << "│" << endl;
}
cout << "└─────────────────────────────────────────────────────────────────┘" << endl;
}
// ============ 特殊边缘测试 ============
void run_edge_cases() {
cout << "\n┌─────────────────────────────────────────────────────────────────┐" << endl;
cout << "│ 边缘测试 │" << endl;
cout << "├─────────────────────────────────────────────────────────────────┤" << endl;
struct EdgeCase {
double a, b;
double expected_math, expected_std;
};
vector<EdgeCase> cases = {
{2.0, 0.0, 1.0, 1.0},
{0.0, 5.0, 0.0, 0.0},
{1.0, 100.0, 1.0, 1.0},
{2.0, 10.0, 1024.0, 1024.0},
{4.0, 0.5, 2.0, 2.0},
{8.0, 1.0/3.0, 2.0, 2.0},
{2.0, -1.0, 0.5, 0.5},
{10.0, -2.0, 0.01, 0.01},
{-2.0, 3.0, -8.0, -8.0},
{-2.0, 2.0, 4.0, 4.0},
{M_E, 1.0, M_E, M_E},
{M_E, 2.0, M_E*M_E, M_E*M_E},
};
cout << "│ " << setw(8) << "a" << setw(8) << "b"
<< setw(15) << "math::pow" << setw(15) << "std::pow"
<< setw(12) << "误差" << " │" << endl;
cout << "├─────────────────────────────────────────────────────────────────┤" << endl;
for (auto& c : cases) {
double math_res = math::pow(c.a, c.b);
double std_res = std::pow(c.a, c.b);
double err = fabs(math_res - std_res);
cout << "│ " << setw(8) << fixed << setprecision(2) << c.a
<< setw(8) << fixed << setprecision(2) << c.b
<< setw(15) << scientific << setprecision(6) << math_res
<< setw(15) << scientific << setprecision(6) << std_res
<< setw(12) << scientific << setprecision(2) << err
<< " │" << endl;
}
cout << "└─────────────────────────────────────────────────────────────────┘" << endl;
}
// ============ 微基准测试 ============
void micro_benchmark() {
cout << "\n┌─────────────────────────────────────────────────────────────────┐" << endl;
cout << "│ 微基准测试 (特定幂) │" << endl;
cout << "├─────────────────────────────────────────────────────────────────┤" << endl;
struct PowCase {
string name;
double a, b;
};
vector<PowCase> cases = {
{"整数幂", 1.5, 10.0},
{"小数幂", 2.0, 0.5},
{"负指数", 3.0, -5.0},
{"大指数", 1.1, 100.0},
{"小底数", 0.5, 20.0},
{"特殊底数e", M_E, 3.7},
{"特殊底数2", 2.0, 10.5},
{"接近1", 1.0001, 1000.0},
};
const int ITERATIONS = 1000000;
cout << "│ " << setw(15) << "测试"
<< setw(10) << "a" << setw(10) << "b"
<< setw(15) << "math::pow(ns)"
<< setw(15) << "std::pow(ns)"
<< setw(10) << "加速比" << " │" << endl;
cout << "├─────────────────────────────────────────────────────────────────┤" << endl;
for (auto& c : cases) {
volatile double dummy = 0;
// 预热
for (int i = 0; i < 1000; i++) {
dummy += math::pow(c.a, c.b);
dummy += std::pow(c.a, c.b);
}
// math::pow
Timer t1;
for (int i = 0; i < ITERATIONS; i++) {
dummy += math::pow(c.a, c.b);
}
double time_math = t1.elapsed_ns() / ITERATIONS;
// std::pow
Timer t2;
for (int i = 0; i < ITERATIONS; i++) {
dummy += std::pow(c.a, c.b);
}
double time_std = t2.elapsed_ns() / ITERATIONS;
cout << "│ " << setw(15) << left << c.name
<< setw(10) << fixed << setprecision(2) << c.a
<< setw(10) << fixed << setprecision(2) << c.b
<< setw(15) << fixed << setprecision(1) << time_math
<< setw(15) << fixed << setprecision(1) << time_std
<< setw(10) << fixed << setprecision(2) << (time_std / time_math)
<< " │" << endl;
}
cout << "└─────────────────────────────────────────────────────────────────┘" << endl;
}
// ============ 主程序 ============
int main() {
cout << "╔══════════════════════════════════════════════════════════════════╗" << endl;
cout << "║ math::pow vs std::pow 性能对比 ║" << endl;
cout << "║ 编译: g++ -O3 -march=native -std=c++17 -lm ║" << endl;
cout << "║ 硬件: " << sizeof(void*) * 8 << "-bit" << setw(40) << "║" << endl;
cout << "╚══════════════════════════════════════════════════════════════════╝" << endl;
vector<TestCase> test_cases = {
{"随机底数 1-100, 随机指数 0-5", 1.0, 100.0, 0.0, 5.0, 1000000},
{"随机底数 0.01-1, 随机指数 1-20", 0.01, 1.0, 1.0, 20.0, 1000000},
{"大底数 1-1000, 小指数 0-1", 1.0, 1000.0, 0.0, 1.0, 1000000},
{"小底数 0-1, 大指数 1-50", 0.0, 1.0, 1.0, 50.0, 1000000},
{"负底数, 整数指数", -10.0, -0.1, 1.0, 10.0, 1000000},
{"正底数, 负指数", 1.0, 100.0, -5.0, -0.1, 1000000},
};
for (auto& tc : test_cases) {
run_benchmark(tc);
}
return 0;
}
输出:
输
出
╔══════════════════════════════════════════════════════════════════╗
║ math::pow vs std::pow 性能对比 ║
║ 编译: g++ -O3 -march=native -std=c++17 -lm ║
║ 硬件: 64-bit ║
╚══════════════════════════════════════════════════════════════════╝
┌─────────────────────────────────────────────────────────────────┐
│ 测试: 随机底数 1-100, 随机指数 0-5 │
├─────────────────────────────────────────────────────────────────┤
│ 实现 总时间(ms) 平均(ns) 吞吐(M ops/s)│
├─────────────────────────────────────────────────────────────────┤
│ math::pow 9.419 9.4 106.17 │
│ std::pow 9.396 9.4 106.43 │
├─────────────────────────────────────────────────────────────────┤
│ 🚀 加速比: 1.00x (std::pow更快) │
│ ✅ 精度验证: 完全匹配 (误差 < 1e-9) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 测试: 随机底数 0.01-1, 随机指数 1-20 │
├─────────────────────────────────────────────────────────────────┤
│ 实现 总时间(ms) 平均(ns) 吞吐(M ops/s)│
├─────────────────────────────────────────────────────────────────┤
│ math::pow 9.394 9.4 106.45 │
│ std::pow 9.372 9.4 106.70 │
├─────────────────────────────────────────────────────────────────┤
│ 🚀 加速比: 1.00x (std::pow更快) │
│ ✅ 精度验证: 完全匹配 (误差 < 1e-9) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 测试: 大底数 1-1000, 小指数 0-1 │
├─────────────────────────────────────────────────────────────────┤
│ 实现 总时间(ms) 平均(ns) 吞吐(M ops/s)│
├─────────────────────────────────────────────────────────────────┤
│ math::pow 9.391 9.4 106.49 │
│ std::pow 9.393 9.4 106.46 │
├─────────────────────────────────────────────────────────────────┤
│ 🚀 加速比: 1.00x (math::pow更快) │
│ ✅ 精度验证: 完全匹配 (误差 < 1e-9) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 测试: 小底数 0-1, 大指数 1-50 │
├─────────────────────────────────────────────────────────────────┤
│ 实现 总时间(ms) 平均(ns) 吞吐(M ops/s)│
├─────────────────────────────────────────────────────────────────┤
│ math::pow 9.372 9.4 106.70 │
│ std::pow 9.412 9.4 106.25 │
├─────────────────────────────────────────────────────────────────┤
│ 🚀 加速比: 1.00x (math::pow更快) │
│ ✅ 精度验证: 完全匹配 (误差 < 1e-9) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 测试: 负底数, 整数指数 │
├─────────────────────────────────────────────────────────────────┤
│ 实现 总时间(ms) 平均(ns) 吞吐(M ops/s)│
├─────────────────────────────────────────────────────────────────┤
│ math::pow 6.049 6.0 165.31 │
│ std::pow 5.764 5.8 173.51 │
├─────────────────────────────────────────────────────────────────┤
│ 🚀 加速比: 0.95x (std::pow更快) │
│ ✅ 精度验证: 完全匹配 (误差 < 1e-9) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 测试: 正底数, 负指数 │
├─────────────────────────────────────────────────────────────────┤
│ 实现 总时间(ms) 平均(ns) 吞吐(M ops/s)│
├─────────────────────────────────────────────────────────────────┤
│ math::pow 9.405 9.4 106.33 │
│ std::pow 9.382 9.4 106.59 │
├─────────────────────────────────────────────────────────────────┤
│ 🚀 加速比: 1.00x (std::pow更快) │
│ ✅ 精度验证: 完全匹配 (误差 < 1e-9) │
└─────────────────────────────────────────────────────────────────┘
这么看来,其实__builtin_pow是稍快一些的。
这里空空如也

















有帮助,赞一个