2013-05-26 36 views
5

std::vector存儲它是在連續的存儲元件相對於std::list。當遍歷元素時,這會給std::vector帶來更好的性能,因爲當迭代std::list時,所有東西都是整齊排列的,而跳過所有內存。是存儲在標準::向量指針破壞它的優勢的連續存儲器存儲

問題是大多數我智能指針存儲在矢量多態性或用於與代碼的其他部分共享這些對象的時間。由於每個對象現在都是動態分配的,因此我認爲它們會在不同的內存位置結束這是否破壞了使用std::vector的目的,並將它變成類似std::list的東西?有什麼可以解決這個問題嗎?

+4

'std :: vector'的目的是爲了簡化存儲元素。無論您是將指針放在那裏還是對象,這都是它的目的,而不是擊敗它。 –

+0

如果你測量,我想你會發現遍歷向量或列表(或任何其他可迭代容器)的迭代不會有任何明顯的差異。 –

+2

@JoachimPileborg也許你應該嘗試測量它。你會驚訝...... :) – jalf

回答

1

不,這不是毫無意義的。

當在可能的智能指針的std::list迭代,你跳近隨機點在內存中的每個迭代增量。訪問時,您再次跳轉到內存中的一個幾乎隨機的點。

如果您在可能的智能指針的std::vector中執行了相同的迭代訪問,則只會跳到內存中幾乎隨機的一個點。

你怎麼能做出這樣痛苦少?

如果您使用的是std::shared_ptr,請記住做std::make_shared,以便ref計數器和數據處於相同的分配狀態,從而減少高速緩存未命中。

如果您只是將它用於多態性,理論上您可以改爲存儲類似於boost::variant(或各種類型的union)以及說明類型是什麼的東西),這允許存在多種類型的變量在同一個地址(一次一個,自然而然)。

+0

從未使用'placement new',但是可以使用它來分配'std :: vector'的成員,以便將它們連續放置在內存中。還是我要求更多的麻煩而不是它的價值? :) –

+0

你可以創建一個僞''boost :: any''(限制爲你的基類'T'的子類),我可以稱之爲「小對象優化」,它爲給定的子類使用放置'new'類。而通過「小班」,我的意思是溫和地比基礎班大一些。或者你可能會亂搞分配器。 – Yakk

4

我認爲std::vector優於std::list的最大優點是索引是O(1)而不是O(n)操作。你在談論的是更多的二階優化。此外,你總是可以自由地將自己的對象存儲在一個大陣列中,然後你不會像過去那樣跳過(如果緩存的目的是你想的)。

+0

+1例如刪除矢量中的每個動態分配元素:'for i - vector.size( )刪除向量[i];'這將是一個很好的用例 –

+0

我不同意:'std :: deque'也有O(1)索引,但是你應該避免使用它,因爲你應該避免使用'std :: list':不平凡的表現擊中了不平凡的表現。 – Yakk

0

std::vector在遍歷它並調用每個多態對象上的一些虛擬方法時,仍然會具有局部優勢,與std::list相比仍具有局部優勢。

現在,因爲你每次都可能調用不同的功能,這是由他們的實際類型的對象進行排序,以避免指令緩存缺失是一個好主意。