如何正确测量计算时间?
变式1:
std::chrono::time_point<std::chrono::system_clock> start, end;
float elapsed = 0;
int N = 100;
for(int i=0; i<N; ++i)
{
start = std::chrono::system_clock::now();
func();//target function
end = std::chrono::system_clock::now();
elapsed += std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
}
变式2:
start = std::chrono::system_clock::now();
for(int i=0; i<N; ++i)
func();
end = std::chrono::system_clock::now();
elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
这些变体显示了截然不同的结果:我试图用std :: function替换虚函数:
struct Base
{
virtual void f() = 0;
};
struct Der1 : public Base
{
virtual void f() override
{
int i=0;
for(int j=0; j<100; ++j)
i += 2*j;
}
};
struct Der2 : public Base
{
virtual void f() override
{
int i=0;
for(int j=0; j<100; ++j)
i += 3*j;
}
};
struct Base_
{
Base_(std::function<void()> f_) : f(f_) {}
std::function<void()> f;
};
struct Der1_ : public Base_
{
Der1_() : Base_([]{
int i=0;
for(int j=0; j<100; ++j)
i += 2*j;
}){}
};
struct Der2_ : public Base_
{
Der2_() : Base_([]{
int i=0;
for(int j=0; j<100; ++j)
i += 3*j;
}){}
};
void process1(std::vector<Base_*>& v)
{
for(auto &elem : v)
elem->f();
}
void process2(std::vector<Base*>& v)
{
for(auto &elem : v)
elem->f();
}
int main()
{
std::vector<Base_*> vec1;
vec1.push_back(new Der1_);
vec1.push_back(new Der2_);
vec1.push_back(new Der1_);
vec1.push_back(new Der2_);
std::vector<Base*> vec2;
vec2.push_back(new Der1);
vec2.push_back(new Der2);
vec2.push_back(new Der1);
vec2.push_back(new Der2);
std::chrono::time_point<std::chrono::system_clock> start1, end1, start2, end2;
float elapsed1 = 0;
float elapsed2 = 0;
int N = 6000;
//Variant 2
start1 = std::chrono::system_clock::now();
for(int i=0; i<N; ++i)
process1(vec1);
end1 = std::chrono::system_clock::now();
elapsed1 = std::chrono::duration_cast<std::chrono::microseconds>(end1-start1).count();
start2 = std::chrono::system_clock::now();
for(int i=0; i<N; ++i)
process2(vec2);
end2 = std::chrono::system_clock::now();
elapsed2 = std::chrono::duration_cast<std::chrono::microseconds>(end2-start2).count();
std::cout<<"virtual: "<<elapsed2<<"\npointer: "<<elapsed1;
for(int i=0; i<vec1.size(); ++i)
delete vec1[i];
for(int i=0; i<vec2.size(); ++i)
delete vec2[i];
return 0;
}
我想了解std :: function上替换虚函数的性能是否有所提升。第二个变量表示2.5-3增益,而第一个变量表示性能下降。
答案 0 :(得分:1)
您在时间上有所不同的最可能原因是分配到end
所花费的时间,这将为您的计数器增加额外的时间。第二种方法是以计算循环中增加i
所花费的时间为代价来避免这种情况,这可能会显着减少。
答案 1 :(得分:1)
在你测量的第一个:
N*(t_func+t_now)
在你测量的第二个:
N*t_func+t_now+t_loop_overhead
如果t_func很小并且t_now与那个相当......
阅读微观基准
答案 2 :(得分:0)
这真的取决于你测量的原因。第一种变体更好一点,只有100次迭代并不是那么多,当然这很大程度上取决于你的“功能”。但是不要以为每次调用都需要花费相同的时间,今天处理器,管道和其他组件都非常困难(而且很聪明)所以如果你需要真正准确的价值,最好找一些现有的测量测试框架,否则你需要自己处理缓存,预测等。
答案 3 :(得分:0)
我最近使用的代码std::sort
与qsort
的时间安排(这里是std::sort
的一个)
#include <algorithm>
#include <array>
#include <chrono>
#include <climits>
#include <iostream>
#include <random>
using std::chrono::duration_cast;
using std::chrono::milliseconds;
using std::chrono::high_resolution_clock;
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution{INT_MIN, INT_MAX};
constexpr auto size = 100000000;
std::array<int, size> data;
int main() {
auto start = high_resolution_clock::now();
std::generate(std::begin(data), std::end(data), std::bind(distribution, generator));
auto gen = high_resolution_clock::now();
std::sort(std::begin(data), std::end(data));
auto finish = high_resolution_clock::now();
std::cout <<
static_cast<double>(duration_cast<milliseconds>(finish - gen).count())/1000 <<
"s for std::sort" << std::endl;
}
顺便说一句std:sort
在我的电脑上快了近2倍。