C++中vector和數(shù)組之間的轉換及其效率問題詳解
因為一些原因,本人遇到需要頻繁把vector與數(shù)組之間轉換的情況,于是就分析了一下兩個之間轉換的實施以及相關的效率問題。
數(shù)組轉換為vector
眾所周知,一維vector中的元素存儲是順序連續(xù)的,所以我們可以通過訪問第一個元素的地址以及元素的數(shù)量來訪問一系列的元素。因此,我們可以采取如下操作來對vector進行訪問和轉換:
先創(chuàng)造一個數(shù)組
int array_size = 1000;
double **array = (double **)malloc(sizeof(double *) * array_size);
for (int i = 0; i < array_size; i++)
array[i] = (double *)malloc(sizeof(double) * array_size);
for (int i = 0; i < array_size; i++)
for (int j = 0; j < array_size; j++)
array[i][j] = i * array_size + j;
method1
// method1
vector<vector<double>> t(array_size, vector<double>(array_size));
for (int i = 0; i < array_size; i++)
{
// 直接定義一個一維的vector,其首地址為數(shù)組的起始地址,末尾地址為最后的地址。
t[i] = vector<double>(array[i], array[i] + array_size);
}
method2
// method2
vector<vector<double>> tt(array_size, vector<double>(array_size));
for (int i = 0; i < array_size; i++)
{
// 直接復制每一個值
for (int j = 0; j < array_size; j++)
tt[i][j] = array[i][j];
}
method3
vector<vector<double>> ttt(array_size, vector<double>(array_size));
for (int i = 0; i < array_size; i++)
{
// 直接使用memcpy進行復制
memcpy(&ttt[i][0], &array[i][0], array_size * sizeof(double));
}
對于上述的三種方法,我簡單的對其進行了效率測試,測試思路是每個都循環(huán)執(zhí)行100遍,看每個方法所需要的時間,測試代碼如下:
clock_t begin, end;
double cost;
begin = clock();
for (int x = 0; x < 100; x++)
{
vector<vector<double>> t(array_size, vector<double>(array_size));
for (int i = 0; i < array_size; i++)
{
t[i] = vector<double>(array[i], array[i] + array_size);
}
}
end = clock();
cost = (double)(end - begin) / CLOCKS_PER_SEC;
printf("method 1 cost: %lf secs\n", cost);
// method2
begin = clock();
for (int x = 0; x < 100; x++)
{
vector<vector<double>> tt(array_size, vector<double>(array_size));
for (int i = 0; i < array_size; i++)
{
for (int j = 0; j < array_size; j++)
tt[i][j] = array[i][j];
}
}
end = clock();
cost = (double)(end - begin) / CLOCKS_PER_SEC;
printf("method 2 cost: %lf secs\n", cost);
// method3
begin = clock();
for (int x = 0; x < 100; x++)
{
vector<vector<double>> ttt(array_size, vector<double>(array_size));
for (int i = 0; i < array_size; i++)
{
memcpy(&ttt[i][0], &array[i][0], array_size * sizeof(double));
}
}
end = clock();
cost = (double)(end - begin) / CLOCKS_PER_SEC;
printf("method 3 cost: %lf secs\n", cost);
多次測試結果基本情況如下:
method 1 cost: 0.388440 secs
method 2 cost: 0.726254 secs
method 3 cost: 0.371002 secs
由此可見,第三種方法是最快的,不過和第一種方法差距不大,第二種方法是最差的,所需時間基本是其他兩種方法的兩倍。
vector轉換為數(shù)組
和數(shù)組轉換為vector的思路基本一致,因為一維的數(shù)組的存儲也是連續(xù)隨機存儲的。
先創(chuàng)造一個vector:
int array_size = 1000;
vector<vector<double>> v(array_size, vector<double>(array_size, 0));
for (int i = 0; i < array_size; i++)
{
for (int j = 0; j < array_size; j++)
{
v[i][j] = i * array_size + j;
}
}
method1
double **array1 = (double **)malloc(sizeof(double *) * array_size);
// method1 因為vector存儲是順序且連續(xù)的,所以可以直接把指向數(shù)組每行首地址的地址指向vector每行的首地址
// 上面那句話有點繞,解釋在最后
for (int i = 0; i < array_size; i++)
{
array1[i] = &v[i][0];
}
method2
double **array2 = (double **)malloc(sizeof(double *) * array_size);
// method2 直接復制每一個值
for (int i = 0; i < array_size; i++)
{
array2[i] = (double *)malloc(sizeof(double) * array_size);
for (int j = 0; j < array_size; j++)
{
array2[i][j] = v[i][j];
}
}
method3
double **array = (double **)malloc(sizeof(double *) * array_size);
for (int i = 0; i < array_size; i++)
{
// method3 使用memcpy來拷貝數(shù)組的元素
array[i] = (double *)malloc(sizeof(double) * array_size);
memcpy(array[i], &v[i][0], sizeof(double) * array_size);
}
效率測試:因為每個方法的執(zhí)行都是動態(tài)申請內存,而作為程序員一定要關注內存,所以每次malloc使用完之后需要free,但是如果按照最開始的方法,在同一個程序內每個執(zhí)行100遍來測試時間的話,可能會導致因為程序執(zhí)行到最后因為內存使用快滿了而導致速度遍慢,于是,我們每個方法只是執(zhí)行1遍(因為1遍的內存比較?。?,然后比較時間。
測試代碼(注意,這里沒有free,在正式使用的時候要記得free):
clock_t begin, end;
double cost;
// method1
begin = clock();
double **array1 = (double **)malloc(sizeof(double *) * array_size);
for (int i = 0; i < array_size; i++)
{
array1[i] = &v[i][0];
}
end = clock();
cost += (double)(end - begin) / CLOCKS_PER_SEC;
printf("method 1 cost: %lf secs\n", cost);
// method2
begin = clock();
double **array2 = (double **)malloc(sizeof(double *) * array_size);
for (int i = 0; i < array_size; i++)
{
array2[i] = (double *)malloc(sizeof(double) * array_size);
for (int j = 0; j < array_size; j++)
{
array2[i][j] = v[i][j];
}
}
end = clock();
cost = (double)(end - begin) / CLOCKS_PER_SEC;
printf("method 2 cost: %lf secs\n", cost);
// method3
begin = clock();
double **array3 = (double **)malloc(sizeof(double *) * array_size);
for (int i = 0; i < array_size; i++)
{
array3[i] = (double *)malloc(sizeof(double) * array_size);
memcpy(array3[i], &v[i][0], sizeof(double) * array_size);
}
end = clock();
cost = (double)(end - begin) / CLOCKS_PER_SEC;
printf("method 3 cost: %lf secs\n", cost);
多次測試結果大致如下:
method 1 cost: 0.000006 secs
method 2 cost: 0.007973 secs
method 3 cost: 0.003540 secs
由此可見第一種方法的速度最快,而且遠遠塊于其他兩種方法,第二種方法是第三種方法時間的兩倍。
結論,直接賦值指針速度>使用memcpy>挨個賦值。
指針與數(shù)組
我們可以看到在上面vector轉化為數(shù)組的中,第一種方法比其他快很多,其具體是怎么實現(xiàn)的呢,解釋如下:
二維數(shù)組的聲明
二維數(shù)組的聲明有幾種方法,下面介紹其中的一種方法:
// 聲明一個指向指針的指針,有array_size個這樣的指針。
double **array = (double **)malloc(sizeof(double *) * array_size);
// 每個指向指針的指針指向一個一維數(shù)組的首地址,其一維數(shù)組的長度為array_size。
for (int i = 0; i < array_size; i++)
array[i] = (double *)malloc(sizeof(double) * array_size);

如上圖所示,array是指向指針的指針,其內容為array[0]的地址,而array[0]的內容為array[0][0]的地址,array[0][0]的內容即為每個元素的值。
第一種方法的解釋
我們首先聲明一個指向指針的指針,其長度為array_size,也就是說,有array_size個指針。
然后每個指針將其內容改為每行vector的首地址,這樣就可以訪問每個元素了。
總結
到此這篇關于C++中vector和數(shù)組之間的轉換及其效率問題的文章就介紹到這了,更多相關C++中vector和數(shù)組轉換內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++實現(xiàn)CreatThread函數(shù)主線程與工作線程交互的方法
這篇文章主要介紹了C++實現(xiàn)CreatThread函數(shù)主線程與工作線程交互的方法,是Windows應用程序設計中非常實用的方法,需要的朋友可以參考下2014-10-10
C/C++?Qt?TableDelegate?自定義代理組件使用詳解
TableDelegate自定義代理組件的主要作用是對原有表格進行調整,本文主要介紹了QT中TableDelegate?自定義代理組件的使用教程,感興趣的朋友可以了解一下2021-12-12
C++實現(xiàn)LeetCode(138.拷貝帶有隨機指針的鏈表)
這篇文章主要介紹了C++實現(xiàn)LeetCode(138.拷貝帶有隨機指針的鏈表),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下2021-07-07
VSCode插件開發(fā)全攻略之package.json詳解
這篇文章主要介紹了VSCode插件開發(fā)全攻略之package.json的相關知識,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05

