C++:几种callable实现方式的性能对比
C++中几种callable实现方式的性能对比
前言
C++中想实现一个callable的对象,通常有四种方式:
std::function:最common的方式,一般会配合std::bind使用。- function pointer:最C的方式,但没办法实现有状态的callable object。
- function object:就是重载了
operator()的类,C++98的STL中经常用。 - lambda expression:不会污染namespace,一般来说编译器内部会实现为一个匿名的function object。
从原理上性能最好的应该是3和4,其次是2,最差的是std::function。下面我们用一小段代码来测试它们的性能。
测试结果
- 测试机器:15' rMBP。
- 编译器:Apple LLVM version 8.1.0 (clang-802.0.42)。
- 编译方式:g++ test.cpp -std=c++14 -O2。
./a.out "std::function" 0.15s user 0.20s system 98% cpu 0.358 total
./a.out "function_pointer" 0.10s user 0.11s system 98% cpu 0.209 total
./a.out "function_object" 0.03s user 0.01s system 92% cpu 0.042 total
./a.out "lambda" 0.03s user 0.01s system 93% cpu 0.042 total
可以看到3和4只要42ms,而相对应的2需要209ms,1需要358ms。这个顺序符合我们的预期,但相差这么多还是比较意外的。
测试程序
#include <iostream>
#include <functional>
#include <vector>
#include <string>
#include <utility>
using namespace std;
template <typename HandlerT = std::function<void (int)>>
class Worker{
public:
explicit Worker(const HandlerT& handler): mHandler(handler) {}
void Run(int x) {
mHandler(x);
}
private:
HandlerT mHandler;
};
template <typename HandlerT>
void Test(HandlerT&& h) {
using WorkerT = Worker<HandlerT>;
vector<WorkerT> v;
for (int i = 0; i < 10000000; ++i) {
v.emplace_back(std::forward<HandlerT>(h));
}
int j = 0;
for (auto& w: v) {
w.Run(++j);
}
}
void Func(int x) {
int y = x + 5;
y += 3;
}
struct Functor {
void operator()(int x) const {
int y = x + 5;
y += 3;
}
};
int main(int argc, char** argv) {
if (argc != 2) {
cerr << "error input" << endl;
exit(1);
}
string mode{argv[1]};
if (mode == "std::function") {
Test(bind(Func, placeholders::_1));
} else if (mode == "function_pointer") {
Test(Func);
} else if (mode == "function_object") {
Test(Functor{});
} else if (mode == "lambda") {
Test([](int x) -> void {int y = x + 5; y += 3;});
} else {
cerr << "error mode:" << mode << endl;
exit(1);
}
}
C++:几种callable实现方式的性能对比的更多相关文章
- ArrayList和LinkedList的几种循环遍历方式及性能对比分析
最新最准确内容建议直接访问原文:ArrayList和LinkedList的几种循环遍历方式及性能对比分析 主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性 ...
- Java 集合 ArrayList和LinkedList的几种循环遍历方式及性能对比分析 [ 转载 ]
Java 集合 ArrayList和LinkedList的几种循环遍历方式及性能对比分析 @author Trinea 原文链接:http://www.trinea.cn/android/arrayl ...
- ArrayList和LinkedList的几种循环遍历方式及性能对比分析(转)
主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性能测试对比,根据ArrayList和LinkedList的源码实现分析性能结果,总结结论. 通过本文你可以 ...
- ArrayList和LinkedList的几种循环遍历方式及性能对比分析(转载)
原文地址: http://www.trinea.cn/android/arraylist-linkedlist-loop-performance/ 原文地址: http://www.trinea.cn ...
- 【转】ArrayList和LinkedList的几种循环遍历方式及性能对比分析
原文网址:http://www.trinea.cn/android/arraylist-linkedlist-loop-performance/ 主要介绍ArrayList和LinkedList这两种 ...
- (转)ArrayList和LinkedList的几种循环遍历方式及性能对比分析
主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性能测试对比,根据ArrayList和LinkedList的源码实现分析性能结果,总结结论. 通过本文你可以 ...
- python中两种栈实现方式的性能对比
在计算机的世界中,同一个问题,使用不同的数据结构和算法实现,所使用的资源有很大差别 为了方便量化python中算法的资源消耗,对性能做测试非常有必要,这里针对stack做了python语言 下的性能分 ...
- HashMap循环遍历方式及其性能对比(zhuan)
http://www.trinea.cn/android/hashmap-loop-performance/ ********************************************* ...
- ArrayList和LinkedList遍历方式及性能对比分析
ArrayList和LinkedList的几种循环遍历方式及性能对比分析 主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性能测试对比,根据ArrayLis ...
随机推荐
- The Die Is Cast(poj 1481简单的双dfs)
http://poj.org/problem?id=1481 The Die Is Cast Time Limit: 1000MS Memory Limit: 10000K Total Submi ...
- CloudFlare CDN折腾记-优化设置
近期又在折腾了,常访问我博客的朋友或许页面曾出现过502错误提示,那是折腾CloudFlare CDN不成功的提示.在此先感谢坛子,在他的执着和求真之下,昨天晚上终于成功使用上CloudFlare C ...
- C:\WINDOWS\system32\drivers\etc\hosts 文件的作用
先来看一看C:\WINDOWS\system32\drivers\etc\hosts 系统原来的hosts文件(未经过改动) 打开原来的hosts文件,查看原来的内容 host是一个没有扩展名的系统文 ...
- CSS中 Zoom属性
CSS中 Zoom属性 其实Zoom属性是IE浏览器的专有属性,Firefox等浏览器不支撑.它可以设置或检索对象的缩放比例.除此之外,它还有其他一些小感化,比如触发ie的hasLayout属性,清除 ...
- Acrobat 无法在本页面上执行OCR识别
下载的电子书有时不能选中,或作黄色标记,在用acrobat pro作文本识别时,报 Acrobat 无法在本页面上执行OCR识别 解决方法 参照 http://jingyan.baidu.com/ar ...
- Postman: Pre-request Script,设置body 变量
1)Postman Pre-request Script 设置变量名 2)把变量放在body里 3)Send后查看变量是否被替换
- Spring,Struts2,MyBatis,Activiti,Maven,H2,Tomcat集成(二)——Struts2集成
1. pom.xml文件添struts2依赖jar包: <!-- 与Struts2集成必须使用 --> <dependency> <groupId>org.spri ...
- C++原创应用类库和工具类库
此博文记载着自编C++应用类库和生成器库的源代码的链接地址,并且对库的开发环境.开发过程.缺陷以及改进更新进行说明. 分数类 利用中午的时间,自己在Visual Studio 2013环境下编写了一个 ...
- [转载] iframe嵌入网页的用法
iframe并不是很常用的,在标准的网页中非常少用.但是有朋友经常问到,下面我简单地介绍一下它的用法,你只要熟练掌握这些参数足矣. <iframe>也应该是框架的一种形式,它与<fr ...
- Web负载均衡学习笔记之四层和七层负载均衡的区别
0x00 简介 简单理解四层和七层负载均衡: ① 所谓四层就是基于IP+端口的负载均衡:七层就是基于URL等应用层信息的负载均衡:同理,还有基于MAC地址的二层负载均衡和基于IP地址的三层负载均衡. ...