使用Chrono衡量性能,顺序似乎很重要,尽管它不应该
measuring performance using chrono, order seems to matter although it shouldn't
作为练习,我正在尝试测量应该执行相同任务的两种算法的效率,对堆栈进行排序,仅使用堆栈作为支持数据结构:
#include <stack>
#include <iostream>
#include <chrono>
std::stack<int> sortStack(std::stack<int>& inS){
std::stack<int> tmpS;
int tmpV=0;
tmpS.push(inS.top());
inS.pop();
while(!inS.empty()){
if(inS.top()>=tmpS.top()){
tmpS.push(inS.top());
inS.pop();
}else{
tmpV = inS.top();
inS.pop();
int count = 0;
//reverse the stack until we find the item that is smaller
while(!tmpS.empty()){
if(tmpS.top()>tmpV){
inS.push(tmpS.top());
tmpS.pop();
count++;
}else{
break;
}
}
//tmpS.top is smaller (or =) than tmpV
tmpS.push(tmpV);
//and revert the other stack
for(int i=0; i< count; i++){
tmpS.push(inS.top());
inS.pop();
}
}
}
return tmpS;
}
std::stack<int> sortStackRevisited(std::stack<int>& inS){
std::stack<int> tmpS;
int tmpV=0;
while(!inS.empty()){
tmpV = inS.top();
inS.pop();
//reverse the stack until we find the item that is smaller
while(!tmpS.empty() && tmpS.top()>tmpV){
inS.push(tmpS.top());
tmpS.pop();
}
tmpS.push(tmpV);
}
return tmpS;
}
int main(){
using namespace std::chrono;
std::stack<int> s1({1,0,123,3,5,89,23,12,1000});
std::stack<int> s({1,0,123,3,5,89,23,12,1000});
auto t1 = high_resolution_clock::now() ;
std::stack<int> ordered = sortStackRevisited(s);
auto t2 = high_resolution_clock::now() ;
std::stack<int> ordered2 = sortStack(s1);
auto t3 = high_resolution_clock::now() ;
std::cout<<"n";
std::cout<<duration_cast<microseconds>(t2-t1).count()<<" "<<duration_cast<microseconds>(t3-t2).count()<<"n";
}
运行这个程序,我始终得到 t2 - t1 大于 t3- t2。如果我更改函数调用的顺序,即:
auto t1 = high_resolution_clock::now() ;
std::stack<int> ordered = sortStack(s);
auto t2 = high_resolution_clock::now() ;
std::stack<int> ordered2 = sortStackRevisited(s1);
auto t3 = high_resolution_clock::now() ;
我仍然认为 t2 - t1 大于 t3- t2。发生了什么事情?我错过了什么吗?
为了编译,我使用g++ --std=c++11 sortStack.cpp
只运行一次代码对于基准测试是不可靠的。您的代码(修复main
后返回int
)在我的机器上运行不到一微秒(使用-O2
因为它应该被优化)。
如果我将其更改为运行代码 100000 次,我会得到的结果是sortStack
比sortStackRevisited
快,无论它们运行顺序如何。
sortStack
先跑:30141 32997
先跑sortStackRevisited
:31244 26642
即使在这里,您也可以看到仅运行 100k 测试时的变化。时间仍然不是很准确。
所以我假设您正在运行未优化的代码并且只执行一次运行,这可能会有各种工件导致结果出现问题。其中之一是您正在测量实时结果,而不是 CPU 时间,这意味着操作系统向运行代码的 CPU 抛出的任何内容都会导致它实时运行速度变慢,即使 CPU 时间相同。或者可能导致 CPU 缓存以不同的方式处理事情,或者这个或那个。有很多可能性。
此外,我机器上未优化的代码运行速度比优化代码慢 20 倍,这表明编译器可以做很多事情来使事情变得更好并影响最终结果。
但是,例如,当将它们相互比较时,将两者运行一百万次将给出相对良好的结果。这两个值会有所不同,但彼此比较时,它们将保持不变。例如,在我的机器上,时间除以另一个是 1.139-1.142,所以很明显另一种方法要慢 14%。如果我只运行 10 次,结果是一次慢 200%。运行 1000 次时,速度会慢 12-28%。因此,正如统计数据所说,更多的尝试会带来更高的准确性。
- 条件断点在不应该触发时触发
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 为什么我不应该把所有东西都放在标题中?
- 找不到 QRegularExpression 行为的任何解释。它有效,但不应该
- 在清除 istream 之前,我不应该需要取消获取它吗?
- c++ 为什么我不应该从不同的线程解锁互斥锁
- "typename"不应该只在模板函数或模板类中使用吗?
- 为不应该获得未定义行为的内容获取未定义的行为
- 两种情况下的输出不应该相同吗?
- 默认情况下,"std::shared_ptr"不应该使用"std::d efault_delete"吗?
- 错误代码 E0065 和 E0169 不应该有
- 矢量的值在不应该更改时更改
- 保证复制省略不应该适用吗?
- 不应该禁止访问私有类型吗?
- 使用匿名命名空间中的函数或另一个文件中的静态函数不应该出错吗?
- NRVO不应该保证局部命名变量和调用站点变量采用相同的地址吗?
- 类的私有成员在我的类实例化期间更改,即使他们不应该
- 为什么'system'不应该在 Windows 特定的应用程序中使用
- 正则表达式在我认为不应该在 c++ 中采用等号
- 使用Chrono衡量性能,顺序似乎很重要,尽管它不应该