簡體   English   中英

C ++字符串內存重用優化

[英]C++ String memory reuse optimization

我想知道tmp字符串內存是否可以在下面的代碼中重用。 是否在每次迭代中重新分配其內存? 有沒有更好的方法來處理這種情況?

string s, line;
map<string, string> mymap;
while(getline(file, line) {
  if(a) s = "_a";
  else if(b) s = "_b";
  string tmp = line + s;
  mymap.insert(tmp, s);
}

每次循環時都會創建和銷毀tmp ,並在line中獲取字符串數據的副本。 因此,您可以獲得廉價的可能的改進,並且幾乎沒有任何差勁,例如:

if(a) s = "_a";
else if(b) s = "_b";
line += s;
mymap.insert(line, s);

我還要給s const char*類型:每個循環只分配一個文字副本的一次分配一個string沒有什么意義。 但是通過insert確實將其轉換為string ,所以兩種方式都沒有太多作用。

只要您不破壞實現代碼的簡單性/可讀性/可維護性/設計性,那么可能的改進和幾乎沒有任何差錯就不是過早的優化。 lines的范圍越大,使用它們玩把戲的風險就越大(分別更改值和更改類型),因為您可能會以某種方式誤導讀者/維護者。 這是短函數良好的原因之一。

在C ++ 11中,您可以編寫mymap.insert(std::move(line), s); 另一個可能的改進。

所有這些說明了:您可能會發現,無論您進行了多少不必要的復制和分配,與getline I / O的時間相比,花費的時間都getline 在這種情況下,有兩種非常相似的代碼編寫方式,其中一種“應該”更有效。 因此,您最好使用它,但不要通過認為它必定會有所作為而高估它。

while循環的每次迭代都會創建並破壞您的字符串tmp對象。 因此,第一步是將tmp移到while循環之外,如已經建議的那樣。 這樣,您不必每次迭代都構造一個新的字符串對象。 但是,您仍然有tmp = line + s分配,這會導致每次迭代進行內存重新分配。 使用= operator創建參數的副本,並將該副本分配給tmp字符串對象。 因此,第二步是添加建議的mymap.insert(line+s, s); 這消除了對tmp字符串對象的需要。

我認為,可以通過不每次迭代都將"_a""_b"分配給字符串s來繼續這種改進。 這可以在while循環之外完成一次,然后根據ab的內容,可以將不同的字符串對象添加到您的映射中。 像這樣的東西(nb未經測試):

string a = "_a";
string b = "_b";
string line;
map<string, string> mymap;
while(getline(file, line) {
  if(a) mymap.insert(line+a, a);
  else if(b) mymap.insert(line+b, b);
}

我認為juanchopanza的答案就足夠了,因為它可以保持代碼的可讀性,因此可以說這是否好。 但是我認為上面的代碼制作的副本較少。

是的,請使用C ++ 11標准中引入的STD :: MOVE語義。

更新:示例

#include <iostream>
#include <utility>
#include <vector>
#include <string>
int main()
{
    std::string str = "Hello";
    std::vector<std::string> v;

    // uses the push_back(const T&) overload, which means 
    // we'll incur the cost of copying str
    v.push_back(str);
    std::cout << "After copy, str is \"" << str << "\"\n";

    // uses the rvalue reference push_back(T&&) overload, 
    // which means no strings will copied; instead, the contents
    // of str will be moved into the vector.  This is less
    // expensive, but also means str might now be empty.
    v.push_back(std::move(str));
    std::cout << "After move, str is \"" << str << "\"\n";

    std::cout << "The contents of the vector are \"" << v[0]
                                         << "\", \"" << v[1] << "\"\n";
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM