STL的速度实验

拿个单调队列的题做试验:

使用STL的代码

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,m,x,f[N];
deque<int>q;

int main(){
	
	freopen("test.in","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&x);
        
        //状态转移 
        if(i<=m)f[i]=x;
        else f[i]=x+f[q.front()];
        
        //f[i]入队的情况 
        while(q.size()&&f[i]<f[q.back()])q.pop_back();
        q.push_back(i);
        
        //front出队的情况
		if(i-q.front()==m){
			q.pop_front();
		} 
    }
    
    printf("%d\n",f[q.front()]);
    return 0;
}

使用数组模拟的代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,m,x,f[N];

//手写队列 
int q[2*N];
int front=0,rear=0;

int main(){
	freopen("test.in","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&x);
        
        //状态转移 
        if(i<=m)f[i]=x;
        else f[i]=x+f[q[front]];
        
        //f[i]入队的情况 
        while(rear!=front && f[i]<f[q[rear]])rear--;
        q[++rear]=i;
        
        //front出队的情况
		if(i-q[front]==m){
			++front;
		} 
    }
    
    printf("%d\n",f[q[front]]);
    return 0;
}

(为了书写方便,这里没有使用循环队列,而是直接开了 2*N 的大小)

然后是随机数据生成器,为了考虑随机性所以直接上mt19937了:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;

std::mt19937 r(std::random_device{}());
int main(){
	freopen("test.in","w",stdout);
	
	int m,n;
	m=r()%N;
	n=r()%N;
	while(m>n)m=r()%N;
	
	printf("%d %d\n",n,m);
	for(int i=1;i<=n;i++)printf("%d ",r()%1000+1);
	
	return 0;
}

首先分别在无优化,-O0,-O1,-O2,-O3的情况下提前编译好可执行文件,然后采用上述的批处理进行反复实验,这样可以得到更为准确的实验结果。

在无优化情况下所截取的平均实验数据:
[average]
deque..202.57ms arr..144.98ms
在无优化情况下,平均时间中STL明显比数组模拟要慢50ms左右。

在-O2优化下,所截取的平均实验数据:
[average]
deque..109.93ms arr..112.16ms

明显地,已经没有太大的区别了,甚至STL略胜一筹。

posted @ 2022-07-10 13:11  计算机知识杂谈  阅读(76)  评论(0编辑  收藏  举报