74 C++的基准测试
1. 基准测试
这里的基准测试不仅仅是你用来对代码进行基准测试的工具,如果你想衡量一段 C++代码的性能,而这段代码本身就需要你正确地去写。 有多种方法可以测量 C++代码的性能,这里只讲述了 Cherno 使用的方法。
首先要写一些我们想测试的代码:
int main()
{
int value = 0;
for (int i = 0; i < 1000000; i++)
value += 2;
std::cout << value << std::endl; // 2000000
__debugbreak(); // VS打断点专用语法
}
现在想要分析我们的代码有多快,可以创建一个简单的、有作用域的计时(可参考63 Timing in C++)
#include <chrono>
class Timer
{
private:
std::chrono::time_point<std::chrono::high_resolution_clock> m_StartTimepoint;
public:
Timer()
{
m_StartTimepoint = std::chrono::high_resolution_clock::now();
}
~Timer()
{
Stop();
}
void Stop()
{
auto endTimepoint = std::chrono::high_resolution_clock::now();
auto start = std::chrono::time_point_cast<std::chrono::microseconds>(m_StartTimepoint).time_since_epoch().count();
auto end = std::chrono::time_point_cast<std::chrono::microseconds>(endTimepoint).time_since_epoch().count();
auto duration = end - start;
double ms = duration * 0.001;
std::cout << duration << "us (" << ms << "ms)\n";
}
};
int main()
{
int value = 0; // 挪到作用域外,保证可以打印出来
{
Timer timer;
for (int i = 0; i < 1000000; i++)
value += 2;
}
std::cout << value << std::endl;
__debugbreak();
}
打印出计时:
这里要注意的是,你要确保自己正在测量的东西是实际上被编译的代码,因为 Release 模式下编译器会优化汇编指令,这个例子中只会记录打印变量 1E8480h(两百万)所需的时间(由于打印在作用域外甚至什么都没统计):
而不是你想统计的加一百万次的用时:
2. 智能指针的性能对比
int main()
{
struct Vector2
{
float x, y;
};
std::cout << "Make Shared\n";
{
std::array < std::shared_ptr<Vector2>, 1000> sharedPtrs;
Timer timer; // 不统计进创造数组的时间
for (int i = 0; i < sharedPtrs.size(); i++)
sharedPtrs[i] = std::make_shared<Vector2>();
}
std::cout << "New Shared\n";
{
std::array < std::shared_ptr<Vector2>, 1000> sharedPtrs;
Timer timer;
for (int i = 0; i < sharedPtrs.size(); i++)
sharedPtrs[i] = std::shared_ptr<Vector2>(new Vector2());
}
std::cout << "Make Unique\n";
{
std::array < std::unique_ptr<Vector2>, 1000> sharedPtrs;
Timer timer;
for (int i = 0; i < sharedPtrs.size(); i++)
sharedPtrs[i] = std::make_unique<Vector2>();
}
__debugbreak();
}
测量两次shared_ptr
和unique_ptr
的性能对比:
和我们所料的差不多,unique_ptr
比shared_ptr
花的时间少,但是make_shared
和new
所差的时间差不多。这里有件很重要的事,我们实际上是在 Debug 模式下分析的,因为它有很多额外的安全措施,需要时间而对测量性能不是很好。
切换到 Release 模式,可以发现make_shared
明显比new
快:
所以一定要确保你所分析的代码,是在 Release 时真正有意义的,因为你不会在 Debug 时发布代码。