2017-03-01 72 views
0

我有這些市場tick數據的大型pcap文件。平均而言,它們每個都是20GB。這些文件被分成數據包。數據包分爲標題和消息。消息分爲標題和字段。字段分爲字段代碼和字段值。將char向量轉換爲字符串的最有效方式

我正在一次讀取文件中的一個字符。我有一個文件讀取器類,它讀取字符並通過const ref將字符傳遞給4個回調函數,on_packet_delimiter,on_header_char,on_message_delimiter,on_message_char。消息對象使用類似的函數來構造它的字段。

到目前爲止,我注意到與僅僅閱讀字符而沒有對它們做任何事情相比,效率損失很小。

我的代碼的一部分,我正在處理消息標題並提取消息的工具符號,這會使流程變得相當慢。

void message::add_char(const char& c) 
{ 
    if (!message_header_complete) { 
    if (is_first_char) { 
     is_first_char = false; 
     if (is_lower_case(c)) { 
     first_prefix = c; 
     } else { 
     symbol_vector.push_back(c); 
     } 
    } else if (is_field_delimiter(c)) { 
     on_message_header_complete(); 
     on_field_delimiter(c); 
    } else { 
     symbol_vector.push_back(c); 
    } 
    } else { 
    // header complete, collect field information 
    if (is_field_delimiter(c)) { 
     on_field_delimiter(c); 
    } else { 
     fp->add_char(c); 
    } 
    } 
} 

... 

void message::on_message_header_complete() 
{ 
    message_header_complete = true; 
    symbol.assign(symbol_vector.begin(),symbol_vector.end()); 
} 

... 

on_message_header_complete()我喂字符來symbol_vector。一旦頭完成,我使用矢量迭代器轉換爲字符串。這是做這件事最有效的方法嗎?

+0

[此'std :: string'構造函數引用](http://en.cppreference.com/w/cpp/string/basic_string/basic_string)應該會有所幫助。 –

+0

如果'symbol'是一個成員變量並且是空的,則它的效率與其獲得的一樣高。 – StoryTeller

+3

儘管我給出了涉及複製的最有效的答案,但我仍然不明白爲什麼你首先需要'std :: vector '。從一開始就使用'std :: string'! –

回答

1

除了量子物理學家的回答是:的std :: string應該表現爲載體確實頗爲相似。即使'保留'功能可用於字符串類,如果你打算使用它來提高效率。

添加字符是一樣容易,因爲它可以得到:

std::string s; 
char c = 's'; 
s += c; 

你可以直接添加字符以您的會員,和你的罰款。但是如果你想保持你的成員乾淨,直到整個字符串被收集,你仍然應該使用std :: string對象而不是vector。然後您將字符添加到臨時字符串,並在完成後,您可以交換的內容。沒有複製,只是指針交換(和一些額外的數據,如容量和大小......)。

+0

感謝球員們,這個方法和.append都極大地提高了速度。平均20736ms vs 35459ms。我會把它放在.append上,因爲它簡單,比平均10次比較中的.append快20ms。對於比我的測試文件大1000倍的主文件,每一點點數都很重要。 – bkarj

+0

您提到了swap函數,它不會複製,而只是交換指針。我很好奇,假設你有一個函數返回一個字符串,並且你在該函數中有一個本地字符串變量來構造返回字符串。當您返回臨時字符串變量時,編譯器會將其複製到返回的值還是交換? – bkarj

+1

@bkarj它會交換 - 但只有自C++ 11以來。如果您針對較舊的標準進行編譯,則會進行復制。看一看[右值引用](http://thbecker.net/articles/rvalue_references/section_01.html)(非常簡短:std :: string爲第2頁提到的'神祕類型'提供了構造函數/賦值運算符)。請注意,通常情況下,在調用此行爲時移動語義只適用於基礎數據類型支持它的情況。 – Aconcagua

1

如何:

std::string myStr(myVec.begin(), myVec.end()); 

雖然這個作品,我不明白爲什麼你需要首先使用向量。從頭開始使用std::string,並使用myStr.append()添加字符或字符串。

下面是一個例子:

std::string myStr = "abcd"; 
myStr.append(1,'e'); 
myStr.append(std::string("fghi")); 
//now myStr is "abcdefghi" 
相關問題