作为练习,我试图衡量应该执行相同任务的两种算法的效率,即仅使用堆栈作为支持数据结构,对堆栈进行排序:
#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
答案 0 :(得分:5)
仅运行一次代码对于基准测试是不可靠的。您的代码(在修复main
后返回int
之后)在我的计算机上运行了不到一秒(使用-O2
,因为它应该被优化)。
如果我将其更改为运行代码100000次,则无论运行什么顺序,它们都会得到sortStack
比sortStackRevisited
更快的结果。
首先运行sortStack
:30141 32997
首先运行sortStackRevisited
:31244 26642
即使在这里,您仅运行10万次测试也可以看到变化。时间仍然不是很准确。
因此,我假设您正在运行未优化的代码,并且仅执行一次运行,该运行可能包含导致结果问题的各种工件。其中之一是您要测量实时结果,而不是CPU时间,这意味着即使操作系统运行的CPU相同,操作系统在运行代码的CPU上抛出的任何信息也会导致其实时运行速度变慢。或可能导致CPU缓存以不同的方式处理此事。有很多可能性。
我的机器上未优化的代码的运行速度也比优化后的代码慢20倍,这表明编译器可以做很多事情来使性能更好并影响最终结果。
但是,如果将两者进行比较,则将它们运行一百万次将获得相对较好的结果。这两个值会有所不同,但是相比较而言,它们将保持不变。例如,在我的机器上,时间除以1.139-1.142,因此,很明显,另一种方法的速度要慢14%。如果我只运行10次,结果将是慢200%。每运行1000次,速度降低12-28%。因此,如统计数据所示,更多尝试会带来更高的准确性。