1. 程式人生 > >C++使用指標和下標遍歷陣列的效率比較

C++使用指標和下標遍歷陣列的效率比較

一直很好奇使用指標和下標遍歷陣列的效率有沒有區別,於是測試了一下,總共測試三種遍歷情況:
1)給陣列每一個元素賦相同的初始值
2)給陣列每一個元素賦隨機數
3)給陣列每一個元素賦當前下標值
三種情況都在g++ 7.0下進行測試,預設使用的C++14標準,分別在預設優化條件(即不加-O情況)和O3優化下進行測試,具體程式碼如下:

#include <iostream>
#include <cstdlib>
using namespace std;
#define N 1000000
int main(){
    srand(clock());
    int *x=(int*)malloc(N*sizeof(int)),*p,*end=x+N;
    clock_t t_start;
    t_start=clock();
    for(int j=0;j<1000;j++){
        for(int i=0;i<N;i++) x[i]=rand();
        //for(int i=0;i<N;i++) x[i]=0;
        //for(int i=0;i<N;i++) x[i]=i;
    }
    cout<<"下標訪問耗時:\n"<<static_cast<double>(clock()-t_start)/CLOCKS_PER_SEC<<endl;
    t_start=clock();
    for(int j=0;j<1000;j++){
        for(p=x;p!=end;p++) *p=rand();
        //for(p=x;p!=end;p++) *p=0;
        //for(p=x;p!=end;p++) *p=p-x;
    }
    cout<<"指標(迭代器)訪問耗時:\n"<<static_cast<double>(clock()-t_start)/CLOCKS_PER_SEC<<endl;
    free(x);
    return 0;
}

最終的測試結果如下:
1)在不使用優化選項時,陣列初始化為零的測試結果是:

下標訪問耗時:
2.63543
指標(迭代器)訪問耗時:
2.09101

而使用了O3優化後的結果是:

下標訪問耗時:
0.155942
指標(迭代器)訪問耗時:
0.153149

2)在不使用優化選項時,陣列用隨機數初始化的測試結果是:

下標訪問耗時:
10.3164
指標(迭代器)訪問耗時:
9.69064

使用O3優化後的結果是:

下標訪問耗時:
9.14839
指標(迭代器)訪問耗時:
9.11899

3)在不使用優化選項時,陣列用下標初始化的測試結果是:

下標訪問耗時:
2.79465
指標(迭代器)訪問耗時:
2.24019

使用O3優化後的結果是:

下標訪問耗時:
0.286373
指標(迭代器)訪問耗時:
0.577319

根據測試結果可以看到,在不開優化的情況下,使用指標(迭代器)遍歷陣列並賦值的效率總是明顯快於下標遍歷,但是在開啟優化後二者的速度差距有所減小,基本還是指標(迭代器)稍快,但是當賦值與當前訪問位置有關時,優化後的指標(迭代器)遍歷的效率會明顯下降,原因可能是指標的減法效率較低。
修改程式碼,使用額外的int變數記錄訪問位置後,再進行測試,程式碼如下:

#include <iostream>
#include <cstdlib>
using namespace std;
#define N 1000000
int main(){
    srand(clock());
    int *x=(int*)malloc(N*sizeof(int)),*p,*end=x+N;
    clock_t t_start;
    t_start=clock();
    for(int j=0;j<1000;j++){
        for(int i=0;i<N;i++) x[i]=i;
    }
    cout<<"下標訪問耗時:\n"<<static_cast<double>(clock()-t_start)/CLOCKS_PER_SEC<<endl;
    t_start=clock();
    int i=0;
    for(int j=0;j<1000;j++){
        for(p=x;p!=end;p++) {*p=i;i++;}
    }
    cout<<"指標(迭代器)訪問耗時:\n"<<static_cast<double>(clock()-t_start)/CLOCKS_PER_SEC<<endl;
    free(x);
    return 0;
}

這時在優化和優化時二者的測試結果如下:
1)不優化

下標訪問耗時:
2.72901
指標(迭代器)訪問耗時:
2.58759

2)優化

下標訪問耗時:
0.313555
指標(迭代器)訪問耗時:
0.290777

可以看到這時依舊是指標(迭代器)較快,因此在進行較大的陣列遍歷時儘量使用指標(迭代器)進行遍歷,儘管可能需要寫的程式碼要多一點,但是相對能夠節省一些執行的時間。尤其是要反覆進行大型陣列遍歷的任務中,使用指標(迭代器)可以有比較明顯的效率提高。