[英]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
,所以兩種方式都沒有太多作用。
只要您不破壞實現代碼的簡單性/可讀性/可維護性/設計性,那么可能的改進和幾乎沒有任何差錯就不是過早的優化。 line
和s
的范圍越大,使用它們玩把戲的風險就越大(分別更改值和更改類型),因為您可能會以某種方式誤導讀者/維護者。 這是短函數良好的原因之一。
在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循環之外完成一次,然后根據a
和b
的內容,可以將不同的字符串對象添加到您的映射中。 像這樣的東西(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.