Lambda 通常比 std::function 更快,因其编译期生成匿名函数对象,调用无间接跳转;而 std::function 依赖类型擦除,存在构造开销、间接调用及缓存不友好等问题。

Lambda 通常比 std::function 更快
Lambda 表达式在编译期生成一个匿名函数对象,调用时等价于普通函数调用(无虚函数、无指针跳转),开销极小。而 std::function 是类型擦除容器,内部通常包含函数指针、成员函数指针或绑定对象的联合体,调用时需通过一层间接跳转(常见为函数指针调用或小对象优化后的直接调用,但仍有额外分支和可能的缓存未命中)。实测中,简单 lambda 调用比同等逻辑的 std::function 快 1.2–2 倍,尤其在高频循环中差异明显。
std::function 的灵活性带来运行时成本
它能统一存储函数指针、lambda、bind 表达式、成员函数等任意可调用体,但这种通用性依赖运行时类型信息和内部调度逻辑。关键代价包括:
- 构造/赋值时可能触发堆分配(当捕获对象较大且未满足小对象优化阈值,如 GCC 默认约 16–32 字节)
- 每次 operator() 调用至少一次间接跳转,无法被内联(除非编译器做激进 LTO 且上下文足够简单)
- 对象尺寸更大(通常 24–48 字节,取决于标准库实现),影响缓存局部性
何时该用 Lambda
适合绝大多数局部、一次性、轻量级场景:
- 作为算法参数(std::sort, std::transform 等)
- 短生命周期回调,不跨作用域传递
- 捕获简单变量(值捕获或 this 指针),且无需类型抹除
- 性能敏感路径,如 inner loop、实时处理、高频事件响应
std::function 不可替代的典型场景
当需要运行时多态、回调注册、延迟执行或接口抽象时,它仍是必要选择:
立即学习“C++免费学习笔记(深入)”;
- 事件系统:注册多个不同来源的回调(lambda、成员函数、全局函数)到同一容器
- 策略模式接口:函数式策略注入,允许外部替换行为
- 异步任务封装:将任意可调用体打包传入线程池或定时器
- 需要拷贝、存储、多次调用且类型不确定的场合
性能优化建议
若必须用 std::function 且关注性能:
- 优先使用值捕获而非引用捕获(避免悬空风险,也利于小对象优化)
- 确保捕获对象总大小 ≤ 实现的小对象缓冲区(可 static_assert sizeof(std::function
) 观察) - 避免频繁构造/赋值;复用已构造对象,或改用函数指针(如果签名固定且无捕获)
- 对极致性能场景,考虑用模板参数替代 std::function(如接受 Callable 模板参数的函数)











