2011-09-28 59 views
2

呈現最少的代碼來描述該問題:優化不必要字符串複製在矢量<string>

struct A { 
    vector<string> v; 
    // ... other data and methods 
}; 
A obj; 
ifstream file("some_file.txt"); 
char buffer[BIG_SIZE]; 
while(<big loop>) { 
    file.getline(buffer, BIG_SIZE-1); 
    // process buffer; which may change its size 
    obj.v.push_back(buffer); // <------- can be optimized ?? 
} 
... 

這裏2倍string創建發生; 第一次創建實際的 string對象,第二次爲 vector複製構建對象。 Demo

push_back()操作發生數百萬次,我支付一個額外的分配那些多次這是沒有用的,我的。

有沒有一種方法來優化呢?我接受任何適當的改變。 (沒有將此分類爲過早優化,因爲push_back()在整個代碼中發生了很多次)。

+1

使用字符串指針的向量? – GWW

+0

@GWW,我對此表示歡迎;但'vector '會比'vector '更好,因爲;一旦緩衝區存儲在'vector'中,它就不會在我的設計中改變。另外,想知道是否有更好的主意。 – iammilind

+1

你可以使用C++ 11移動語義嗎?如果是這樣,那就這樣做。 – GManNickG

回答

3

那麼,你得到兩個撥款,但不能兩者是字符串的:他們中的一個創建的字符串,而另一隻創建一個指針(注意這取決於編譯器:一些編譯器/設置可能確實創建了兩個字符串,但大多數不會)。演示請看this code

優化它的一種方法是使用char *而不是字符串作爲模板參數(不要忘記在殺死vector之前手動刪除它)。這樣你就可以擺脫一個(最大的)分配。另外,只需使用你自己的矢量實現:然後你就可以控制內存分配的每個方面。

3

你可以嘗試幾件事情。第一個顯然是在編譯器上啓用優化。 如果您可以聲明它爲 vector<const string>可能有所幫助。

否則,你可以嘗試這樣的:

obj.v.resize(obj.v.size()+1); 
obj.v.back().swap(string(buffer)); 
+1

這實際上是一個C++ 03程序員如何模擬移動語義。 – GManNickG

+2

'vector '?這甚至是合法的嗎? –

+3

@ K-ballo:不,它不是。該類型必須是可複製分配的,「const string」不滿足。 – GManNickG

0

而不是堆棧上的緩衝區 - 把它放到堆上。然後使用指針向量。只有一個