我過於迂腐的評論太大了,所以我會盡量讓這個有點迂迴的答案。簡短的答案可能只是堅持vector
,但一定要使用reserve
;哦,和基準。
你沒有說你正在使用什麼編譯器或C++版本,所以我只會去我當前gcc.godbolt.org默認的gcc 4.9.2,C++ 14。我也假設你真的希望這是一維數組,而不是更自然(例如)3.
如果你知道在編譯時N
,你可以做這樣的事情(假設我得到了陣列偏移計算正確):
#include <array>
...
std::array<xyz, N*N*N> xyzs;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
for (int k = 0; k < N; k++) {
xyzs[i*N*N+j*N+k] = {i, j, k};
}
}
}
最大缺點,IMO:
- 容易出錯的偏移計算
- 取決於
N
,在碼我的磨合,等,這可以吹堆棧
在我上嘗試這樣的編譯器,優化器似乎明白,我們正在通過在連續的順序在陣列移動,並將所生成的機器代碼是比較明智的,但它也可以寫像這樣,如果你喜歡:
#include <array>
...
std::array<xyz, N*N*N> xyzs;
auto p = xyzs.data();
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
for (int k = 0; k < N; ++k) {
(*p++) = {i, j, k};
}
}
}
當然,如果你真的在編譯時知道N
,也不會吹堆棧,你可能會考慮一個3維數組xyz xyzs[N][N][N];
因爲這些東西最終被使用的方式可能更自然。
正如在註釋中指出的那樣,變長數組不是合法的C++,但它們在C99中是合法的;如果你在編譯時不知道N
,你應該從堆中分配。
A vector
和一個數組將結束在內存佈局方面相同;它們的區別在於vector
從堆中分配內存,並且數組(當您正在寫它時)將在堆棧中。我會做的唯一建議是輸入您的循環之前調用reserve
:
vect.reserve(N*N*N);
這意味着你只能在前面做一個單一的內存分配,而不是成長和複製的機制,你會從默認構建的vector
獲得。
假設xyz
的聲明在這裏就是這麼簡單,你也可以做類似上面的第二個例子:
std::vector<xyz> xyzs{N*N*N};
auto p = xyzs.data();
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
for (int k = 0; k < N; ++k) {
(*p++) = {i, j, k};
}
}
}
你失去的push_back
安全,效率較低,如果xyz
默認的構造函數需要做任何事情(如果xyz
成員被更改爲具有默認值)。
說了這麼多,你真的應該做基準。但是,你可能應該對最終使用這個數組的代碼進行基準測試,而不是代碼來構建它;如果施工占主導地位,我還會有其他擔憂。
您需要使用堆('new'),因爲矢量的大小直到運行時才知道。 – AndyG
你在哪裏得到*因爲數組比處理*的矢量快2倍?正確使用的矢量在速度方面應該與數組幾乎相同。 – NathanOliver
1)VLAs('xyz arr [vect.size()];')是非標準的C++ 2)你認爲?你是否嘗試用_anything_來自己解決問題(例如調試器)? 3)_I想要將該向量轉換爲數組,因爲數組比處理向量快2倍。您在哪裏讀過這些廢話? –