代码
#include <QHash>
#include <QSharedPointer>
#include <chrono>
#include <functional>
#include <iostream>
#include <memory>
#include <optional>
using namespace std;
using namespace std::chrono;
#define COUNT 10000000
//#define TEST_0_CALL
//#define TEST_0_TEMP_CALL
#define TEST_I_CALL
//#define TEST_I_TEMP_CALL
#define PARAMS_DEFINE QString, int, bool, QHash<int, QString>
#define PARAMS_VALUE "", 1, false, QHash<int, QString>()
//#define PARAMS_DEFINE
//#define PARAMS_VALUE
typedef function<void(PARAMS_DEFINE)> TestFunc;
static int v = 0;
void test(PARAMS_DEFINE) {
int a = v + 1;
int b = a + 2;
}
static std::optional<TestFunc> normal = test;
static std::optional<QSharedPointer<TestFunc>> pt = QSharedPointer<TestFunc>(new TestFunc(test));
static QHash<int, std::optional<TestFunc>> normalVector;
static QHash<int, std::optional<QSharedPointer<TestFunc>>> ptVector;
std::optional<TestFunc> getNormal(qint32 idx) { return normalVector.value(idx); }
std::optional<QSharedPointer<TestFunc>> getPt(qint32 idx) { return ptVector.value(idx); }
void runNormal() {
auto m1 = duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
for (int i = 0; i < COUNT; ++i) {
// 1. 取0直接调用
#ifdef TEST_0_CALL
getNormal(0).value()(PARAMS_VALUE);
#endif
// 2. 取0赋值调用
#ifdef TEST_0_TEMP_CALL
auto temp = getNormal(0);
temp.value()(PARAMS_VALUE);
#endif
// 3.取索引直接调用
#ifdef TEST_I_CALL
getNormal(i).value()(PARAMS_VALUE);
#endif
// 4.取索引赋值调用
#ifdef TEST_I_TEMP_CALL
auto temp1 = getNormal(i);
temp1.value()(PARAMS_VALUE);
#endif
}
auto m2 = duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
cout << m2 - m1 << endl;
}
void runSP() {
auto m1 = duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
for (int i = 0; i < COUNT; ++i) {
// 1. 取0直接调用
#ifdef TEST_0_CALL
(*getPt(0).value())(PARAMS_VALUE);
#endif
// 2. 取0赋值调用
#ifdef TEST_0_TEMP_CALL
auto temp = getPt(0);
(*temp.value())(PARAMS_VALUE);
#endif
// 3.取索引直接调用
#ifdef TEST_I_CALL
(*getPt(i).value())(PARAMS_VALUE);
#endif
// 4.取索引赋值调用
#ifdef TEST_I_TEMP_CALL
auto temp1 = getPt(i);
(*temp1.value())(PARAMS_VALUE);
#endif
}
auto m2 = duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
cout << m2 - m1 << endl;
}
int main(int argc, char** argv) {
for (int i = 0; i < COUNT; ++i) {
normalVector.insert(i, normal);
ptVector.insert(i, pt);
}
runNormal();
runSP();
return 0;
}
分析
debug
调用0的情况下,编译器不做临时变量优化,不做std::function优化,此时普通变量多构造std::function性能损耗,调用智能指针多间接调用性能损耗,所以智能指针略优于普通变量
调用i的情况下,与0类似
release
调用0,函数参数简单情况下,编译器做临时变量优化,做std::function优化,此时普通变量构造一次std::function,智能指针多间接调用性能损耗,所以普通变量优于智能指针
调用i,函数参数简单情况下,编译器做std::function优化,普通变量构造std::function,智能指针间接调用,由于参数简单,std::function更快,所以普通变量略优于智能指针
调用i,函数参数复杂情况下,编译器做std::function优化,普通变量构造std::function,智能指针间接调用,由于参数复杂,std::function慢,所以智能指针略优于普通变量
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。