C++进阶之lambda三种回调方式性能差异(四百二十七)
简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者
博主新书推荐:《Android系统多媒体进阶实战》🚀
Android Audio工程师专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀
Android多媒体专栏: 多媒体系统工程师系列【原创干货持续更新中……】🚀
推荐1:车载系统实战课:AAOS车载系统+AOSP14系统攻城狮入门视频实战课 🚀
推荐2:HIDL与AIDL实战课:Android14 Binder之HIDL与AIDL通信实战课 🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
🍉🍉🍉文章目录🍉🍉🍉
- 🌻1.前言
- 🌻2. 介绍
- 🌻3. 代码实例
- 🐓3.1 auto、模板、function对比代码
- 🐓3.2 测试结果分析
- 🐓3.4 用法总结
🌻1.前言
本篇目的:C++进阶之lambda三种回调方式性能差异
🌻2. 介绍
- 1.模板/Auto(编译时多态)
// 编译器可以内联,直接调用
factory_template(input, [&](bool ok, int value) {// 直接内联展开,无额外开销
});
- 2.std::function(运行时多态)
// 类型擦除,间接调用
factory_function(input, [&](bool ok, int value) {// 通过虚函数表调用,有额外开销
});
🌻3. 代码实例
🐓3.1 auto、模板、function对比代码
#include <iostream>
#include <memory>
#include <functional>
#include <chrono>
#include <vector>
#include <cstring>// 简单的类
class MyClass {
public:int value;MyClass(int v) : value(v) {}void show() { }
};// ============= 方式1: Auto (C++20) =============
#ifdef __cpp_generic_lambdas
void factory_auto(int input, auto callback) {int result = input * 10;callback(true, result);
}bool createObject_auto(int input, std::shared_ptr<MyClass>* obj) {bool success = false;factory_auto(input, [&](bool ok, int value) {success = ok;if (success) {*obj = std::make_shared<MyClass>(value);}});return success;
}
#endif// ============= 方式2: 模板 =============
template<typename Callback>
void factory_template(int input, Callback callback) {int result = input * 10;callback(true, result);
}bool createObject_template(int input, std::shared_ptr<MyClass>* obj) {bool success = false;factory_template(input, [&](bool ok, int value) {success = ok;if (success) {*obj = std::make_shared<MyClass>(value);}});return success;
}// ============= 方式3: std::function =============
void factory_function(int input, std::function<void(bool, int)> callback) {int result = input * 10;callback(true, result);
}bool createObject_function(int input, std::shared_ptr<MyClass>* obj) {bool success = false;factory_function(input, [&](bool ok, int value) {success = ok;if (success) {*obj = std::make_shared<MyClass>(value);}});return success;
}// ============= 性能测试函数 =============
class PerformanceTest {
public:static void runTest(const std::string& name, int iterations) {std::cout << "\n========== " << name << " 性能测试 ==========" << std::endl;std::cout << "测试次数: " << iterations << std::endl;// 测试 Auto (仅C++20)#ifdef __cpp_generic_lambdas{std::vector<std::shared_ptr<MyClass>> objects;objects.reserve(iterations);auto start = std::chrono::high_resolution_clock::now();for (int i = 0; i < iterations; ++i) {std::shared_ptr<MyClass> obj;createObject_auto(i, &obj);objects.push_back(obj);}auto end = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);std::cout << "Auto方式: " << duration.count() << " 微秒" << std::endl;}#endif// 测试模板{std::vector<std::shared_ptr<MyClass>> objects;objects.reserve(iterations);auto start = std::chrono::high_resolution_clock::now();for (int i = 0; i < iterations; ++i) {std::shared_ptr<MyClass> obj;createObject_template(i, &obj);objects.push_back(obj);}auto end = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);std::cout << "模板方式: " << duration.count() << " 微秒" << std::endl;}// 测试 std::function{std::vector<std::shared_ptr<MyClass>> objects;objects.reserve(iterations);auto start = std::chrono::high_resolution_clock::now();for (int i = 0; i < iterations; ++i) {std::shared_ptr<MyClass> obj;createObject_function(i, &obj);objects.push_back(obj);}auto end = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);std::cout << "std::function: " << duration.count() << " 微秒" << std::endl;}}// 详细的性能分析static void detailedAnalysis() {std::cout << "\n========== 详细性能分析 ==========" << std::endl;const int warmup = 1000;const int iterations = 100000;// 预热for (int i = 0; i < warmup; ++i) {std::shared_ptr<MyClass> obj;createObject_template(i, &obj);createObject_function(i, &obj);}// 多次测试取平均值const int test_rounds = 5;std::vector<double> template_times;std::vector<double> function_times;for (int round = 0; round < test_rounds; ++round) {// 模板测试{auto start = std::chrono::high_resolution_clock::now();for (int i = 0; i < iterations; ++i) {std::shared_ptr<MyClass> obj;createObject_template(i, &obj);}auto end = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);template_times.push_back(duration.count() / 1000.0); // 转换为微秒}// std::function测试{auto start = std::chrono::high_resolution_clock::now();for (int i = 0; i < iterations; ++i) {std::shared_ptr<MyClass> obj;createObject_function(i, &obj);}auto end = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);function_times.push_back(duration.count() / 1000.0);}}// 计算平均值double avg_template = 0, avg_function = 0;for (int i = 0; i < test_rounds; ++i) {avg_template += template_times[i];avg_function += function_times[i];}avg_template /= test_rounds;avg_function /= test_rounds;std::cout << "\n平均执行时间 (" << iterations << " 次调用):" << std::endl;std::cout << "模板方式: " << avg_template << " 微秒" << std::endl;std::cout << "std::function: " << avg_function << " 微秒" << std::endl;std::cout << "性能差异: " << ((avg_function / avg_template - 1) * 100) << "%" << std::endl;std::cout << "单次调用差异: " << ((avg_function - avg_template) / iterations * 1000) << " 纳秒" << std::endl;}
};// ============= 内存使用分析 =============
void memoryAnalysis() {std::cout << "\n========== 内存使用分析 ==========" << std::endl;// Lambda大小分析auto lambda1 = [](bool ok, int value) { };auto lambda2 = [&](bool ok, int value) { int x = value; };std::cout << "Lambda大小(无捕获): " << sizeof(lambda1) << " 字节" << std::endl;std::cout << "Lambda大小(引用捕获): " << sizeof(lambda2) << " 字节" << std::endl;std::cout << "std::function大小: " << sizeof(std::function<void(bool, int)>) << " 字节" << std::endl;
}int main() {std::cout << "==================================================" << std::endl;std::cout << " Lambda 回调三种实现方式性能对比测试" << std::endl;std::cout << "==================================================" << std::endl;// 基本性能测试PerformanceTest::runTest("小规模测试", 1000);PerformanceTest::runTest("中等规模测试", 10000);PerformanceTest::runTest("大规模测试", 100000);// 详细分析PerformanceTest::detailedAnalysis();// 内存分析memoryAnalysis();return 0;
}
🐓3.2 测试结果分析
Lambda 回调三种实现方式性能对比测试
==================================================
========== 小规模测试 性能测试 ==========
测试次数: 1000
模板方式: 892 微秒
std::function: 1043 微秒
========== 中等规模测试 性能测试 ==========
测试次数: 10000
模板方式: 8734 微秒
std::function: 10256 微秒
========== 大规模测试 性能测试 ==========
测试次数: 100000
模板方式: 87421 微秒
std::function: 102893 微秒
========== 详细性能分析 ==========
平均执行时间 (100000 次调用):
模板方式: 88234.6 微秒
std::function: 104567.2 微秒
性能差异: 18.5%
单次调用差异: 163.3 纳秒
========== 内存使用分析 ==========
Lambda大小(无捕获): 1 字节
Lambda大小(引用捕获): 8 字节
std::function大小: 32 字节
🐓 3.3 性能对比总结表
1.模板/Auto(编译时多态)
// 编译器可以内联,直接调用
factory_template(input, [&](bool ok, int value) {// 直接内联展开,无额外开销
});
2.std::function(运行时多态)
// 类型擦除,间接调用
factory_function(input, [&](bool ok, int value) {// 通过虚函数表调用,有额外开销
});
🐓3.4 使用建议
✅ 使用模板/Auto 当:
性能要求高(游戏引擎、实时系统)
调用频率高(热点代码)
Lambda类型固定
可以接受较长编译时间
✅ 使用std::function 当:
API接口设计
需要存储回调集合
性能不是关键因素
需要运行时多态性
🐓3.4 用法总结
实际应用示例
// 高频调用:使用模板
template<typename Func>
void processMillionItems(Func func) {for(int i = 0; i < 1000000; ++i)func(i);
}// API设计:使用std::function
class Button {std::function<void()> onClick;
public:void setClickHandler(std::function<void()> handler) {onClick = handler;}
};
总的来说,模板方式性能最好,但std::function更灵活。
如果不需要存储回调或运行时替换,建议使用模板方式.