[英]Calculating size of vector of vectors in bytes
typedef vector<vector<short>> Mshort;
typedef vector<vector<int>> Mint;
Mshort mshort(1 << 20, vector<short>(20, -1)); // Xcode shows 73MB
Mint mint(1 << 20, vector<int>(20, -1)); // Xcode shows 105MB
short使用2個字節,int使用4個字節; 請注意1 << 20 = 2^20
;
我正在嘗試提前計算(在紙上)內存使用量,但無法計算。
sizeof(vector<>) // = 24 //no matter what type
sizeof(int) // = 4
sizeof(short) // = 2
我不明白: mint
應該是mshort
兩倍,但事實並非如此。 僅在使用mshort
初始化運行程序時, Xcode顯示73MB的內存使用情況; mint
105MB ;
mshort.size() * mshort[0].size() * sizeof(short) * sizeof(vector<short>) // = 1006632960
mint.size() * min[0].size() * sizeof(int) * sizeof(vector<int>) // = 2013265920
//no need to use .capacity() because I fill vectors with -1
1006632960 * 2 = 2013265920
如何計算2d std::vector
使用或2d std::array
使用多少RAM空間。
我知道前面的大小,每一行都有相同的列數。
向量的向量在內存中的使用例如
// the size of the data...
mshort.size() * mshort[0].size() * sizeof(short) +
// the size of the inner vector objects...
mshort.size() * sizeof mshort[0] +
// the size of the outer vector object...
// (this is ostensibly on the stack, given your code)
sizeof mshort +
// dynamic allocation overheads
overheads
動態分配開銷是因為vector
在內部為其要存儲的元素提供了new
內存,並且出於速度方面的考慮,它們可能有固定大小的內存區域池等待新的請求,因此,如果vector
有效地執行了一個new short[20]
-數據需要40個字節-最終可能會以48或64結尾。實現可能實際上需要使用一些額外的內存來存儲數組大小,盡管short
, int
和int
並不需要遍歷元素調用在delete[]
期間使用析構函數,因此良好的實現將避免這種分配和no-op破壞行為。
但是,任何給定向量的實際數據元素在內存中都是連續的,因此,如果要減少開銷,可以更改代碼以使用更少,更大的vector
。 例如,使用一個(1 << 20) * 20
vector
開銷可以忽略不計-然后可以訪問[i * 20 + j]
而不是訪問[i][j]
[i * 20 + j]
-您可以編寫一個簡單的類來包裝vector
為此,最簡單的方法是使用v(i, j)
表示法...
inline short& operator()(size_t i, size_t j) { return v_[i * 20 + j]; }
inline short operator()(size_t i, size_t j) const { return v_[i * 20 + j]; }
...盡管您可以通過讓v.operator[]
返回一個可以用[]
進一步建立索引的代理對象來支持v[i][j]
[]
。 我確定如果您在多維數組上搜索問題,將有一些示例-認為我自己可能曾經發布過此類代碼。
想要vector<vector<x>>
主要原因是當內部vector
s的長度變化時。
假設glibc malloc:每個內存塊將為內存塊頭分配額外的8-16字節(2 size_t)。 對於64位系統,它將是16個字節。 參見代碼: https : //github.com/sploitfun/lsploits/blob/master/glibc/malloc/malloc.c#L1110
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk, if allocated | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of chunk, in bytes |M|P|
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| User data starts here... .
. .
. (malloc_usable_size() bytes) .
. |
每行添加16個字節時,它的總長度約為83886080。
26 + 16 + mshort.size(1048576)*(mshort [0] .size(20)* sizeof(short(2))+ sizeof(vector(26))+ header(16))
它為我提供了大約125829120的整數。
但是后來我重新計算了你的數字,看起來你在32位上...
看起來非常接近報告的那些。
即使您的情況相同,也請使用容量而非大小來獲取#items號。
分配單個向量大小的行*列將節省標題* 1048576字節。
您的計算mshort.size() * mshort[0].size() * sizeof(short) * sizeof(vector<short>) // = 1006632960
是完全錯誤的。 根據您的計算, mshort
需要1006632960,即960MiB,這是不正確的。
讓我們忽略的libc的開銷,並且僅僅關注std::vector<>
的尺寸: mshort
是一個vector
的1^20
項,每項是vector<short>
與20個項目。 因此大小應為:
mshort.size() * mshort[0].size() * sizeof(short) // Size of all short values + mshort.size() * sizeof(vector<short>) // Size of 1^20 vector<short> + sizeof(mshort) // Size of mshort itself, which can be ignored as overhead
計算的大小為64MiB 。
與mint相同,其中計算的大小為104MiB 。
因此, mint
根本不是 mshort
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.