2010-10-11 58 views
1

我想知道存儲向量/數據數組(int或double)的性能方面的最佳解決方案,其維數在編譯時不可用(取決於來自用戶的輸入),但一旦初始化,它們將永遠不會改變它們的尺寸,也不會改變它們的值。換句話說,我想知道是否使用不同於矢量的東西可以提高效率,因爲我確信我的矢量的尺寸和內容在初始化後不會改變。 謝謝 阿爾貝託具有固定尺寸和值的向量(C++)

+0

你是什麼效率呢?訪問個別元素的成本?是什麼讓你認爲這是一個問題?你有沒有分析你的代碼來驗證這個假設? – 2010-10-11 10:45:53

+0

內置數據類型不會妨礙插入,修改或刪除矢量。 – DumbCoder 2010-10-11 10:46:28

+0

..確切地說,你爲什麼認爲'std :: vector'可能不夠? – Arun 2010-10-11 10:47:29

回答

2

好吧,如果你不改變矢量的大小,那麼你將不會有空間的位置。所以矢量仍然是一個不錯的選擇。如果數據不會改變,您可以使用const向量

-1

在整數/雙精度列表中使用它們,示例顯示爲here

+0

這個例子是很醜陋的。壞壓痕,沒有意見,'.h'頭,危險的默認拷貝構造函數和'運營商=',所謂的「名單」的數組,不超載'操作符[]'甚至不告訴對方工作與存儲的對象,混合容器邏輯和UI邏輯...... – 2010-10-11 10:58:43

+0

這只是一個想法:),我沒給的例子給它的代碼複製粘貼,我給它製作一個想法,想想 – 2010-10-11 11:14:23

+0

我完美理解,但如果你提供一個例子,它的確定,它應該只顯示的基本概念,但它不應該充滿錯誤和不好的做法:) – 2010-10-11 11:56:01

5

儘管懷疑暗示了這個問題,但我仍然會嘗試使用std::vector(直到證明相反),並且只要我知道用戶輸入中的維度,就調用成員函數reserve()爲所有元素分配空間。預先調用reserve()可避免重複的內存分配和元素複製。

+0

我同意,但如果大小是真正固定的,你可能想調用「調整大小」而不是「保留」。那麼你可以使用每個元素並且永遠不會調用「push_back」。 – 2010-10-11 11:22:52

+1

@ EDA-QA莫爾 - ORA-Y:IIRC,'調整()'會召喚元素的默認構造函數,但'儲備()'不會。在這種特殊情況下,元素爲「int」或「double」的元素可能無關緊要,但我認爲這是一種很好的做法。而且,在適當調用'reserve()'後,'push_back()'相當於數組索引'vec [i] = new_elem'。 – Arun 2010-10-11 11:44:51

+0

不,'push_back(x)'不等於'vec [i] = x'。使用超出數組大小的索引是無效的,即使它位於*容量*範圍內。 – 2010-10-11 11:53:39

1

std::vector很好。如果你試圖用那裏的數字做數學std::valarray可能是一個不錯的選擇。它也可以被修改和調整大小,但只要你不使用它,一個實現應該不會產生這樣的開銷。

1

如果大小和內容在初始化後真正不會改變,那麼請使用const vector。但是,如果內容非常有趣,這意味着您必須使用複製構造函數或使用迭代器對的構造函數。

這不太可能在優化的方式上有太多的啓用,但值得一試[*]。然而,它強制你的代碼是常量正確的,也就是說,你不僅不需要修改向量,你的代碼必須構成一個特定種類的編譯器(禁止不明智的轉換),你不會修改它矢量。

這是額外的工作,如果你的代碼已經不是常量正確的,但是隨着你沿着編譯器會告訴你需要改變什麼。

[*]我認爲我的意思是,作爲一般慣例,在可能的情況下值得使用const。儘管如此,其原因與性能無關。如果你只是想加快一個特定的程序,開發人員的時間比徹底修正不正確的代碼更有效的用法是常量正確的。但假設它編譯,這是沒有努力做出改變。

0

您的替代選項是boost :: shared_array。它們也是引用計數的,所以你可以在不復制數據的情況下複製shared_array。

shared_array是有限的:你不能從中獲得大小,也不能通過傳遞shared_array來保護你的數據。

所以要做到這一點,你將不得不寫一個包裝,可以做到這兩個。如果你打算寫一個包裝器,你可能只是包裝shared_ptr>,但這意味着更多的分配和更間接,所以shared_array可能是你的朋友。

shared_array不是tr1的一部分。

要使用shared_array,您需要以「舊」的方式分配數據,即在需要數據時使用新的T [N],但shared_array會保護數據的生命週期,因此您不必擔心刪除它只要你不做循環引用)。