2017-05-24 135 views
0

我有一個項目,我使用boost.asio套接字在客戶端和服務器之間傳輸數據。一旦連接的一端接收到數據,它就會將其轉換爲std::stringstd::vector,然後通過先前定義的「回調」函數將其傳遞給數據的實際接收者對象。這種方式迄今爲止工作得很好,只是,我現在正在使用諸如atoi()to_string之類的方法將除字符串以外的其他數據類型轉換爲可發送格式並返回。這種方法當然在網絡使用方面有些浪費(尤其是當傳輸大量數據而不是單個輸入和浮點數時)。因此,我想序列化和反序列化數據。因爲實際上,任何序列化方法都會產生一個字節數組或緩衝區,所以我只需要使用std::string來代替。這樣做有什麼不利嗎?我不明白爲什麼應該有一次,因爲字符串應該不過是字節數組。std ::字符串與字節緩衝區(差異在c + +)

+2

_「這樣做有什麼不利嗎?」_號也許'std :: vector '在語義上可能更清晰。 –

+0

據我所知,'std :: string'幾乎必須以null結束其緩衝區,而'std :: vector '不必。但是,與額外的功能'std :: string'相比,可能不足以滿足性能影響。 –

+0

@DanielSchepler我認爲'std :: string'不是空終止的,只有'string :: c_str'和'string :: data'給你一個空終止的序列 –

回答

4

在功能方面,沒有真正的區別。但是,出於性能原因和代碼清晰的原因,我建議使用std::vector<uint8_t>來代替,因爲它讓任何維護代碼的人都清楚它是一個字節序列,而不是字符串。

+0

等等......你沒有爲你的「表現理由」爭辯, –

1

你說得對。字符串不過是字節數組。 std::string只是管理表示字符串的緩衝區數組的便捷方式。而已!

使用std::string沒有什麼缺點,除非您正在處理某些性能至關重要的性能問題,例如內核......然後使用std::string將會產生相當大的開銷。除此之外,請隨時使用它。

-

std::string幕後需要做一大堆關於字符串的狀態檢查,以決定是否將使用小串的優化與否。今天幾乎所有的編譯器都實現了小字符串優化。他們都使用不同的技術,但基本上它需要測試位標記,以確定字符串是否將構建在堆棧或堆中。如果您直接使用char[],則此開銷不存在。但是,除非你正在研究一些非常關鍵的內核,否則你將不會注意到任何東西,並且std::string更方便。

同樣,這只是其中一件事發生在引擎蓋下,僅僅作爲一個例子來展示它們的不同之處。

+2

來自'std :: string'的「相當大的開銷」......真的嗎? –

+0

是的,如果在內核級別使用'std :: string',開銷非常可觀。這裏是一個例子......但還有更多:https://stackoverflow.com/questions/21946447/how-much-performance-difference-when-using-string-vs-char-array –

+1

@ÐаnI不要個人知道細節,但'std :: string'有一小部分額外開銷,因爲它有幾個需要遵守的約束,包括但不限於它需要總是有一個額外的事實分配給空字符的字節。但同時,'std :: string'對象可以接受「小字符串優化」,這可以改善內存佔用。關鍵的一點是'std :: string'可以完成你可能不期望的事情。 – Xirema

-2

根據你發射網絡消息的頻率,std::string應該沒問題。這是一個便利的班級,可爲您處理大量的char工作。如果你有大量的數據可以推送,那麼直接使用char陣列並將其轉換爲字節可能是值得的,只是爲了儘量減少std::string所帶來的額外開銷。

編輯:如果有人可以評論並指出爲什麼你認爲我的答案不好,那會很棒,並幫助我學習。

3

當你使用字符串時,你應該使用std::string,當你使用二進制blob時,你最好使用std::vector<uint8_t>。有很多好處:

  • 你的意圖很明顯這樣的代碼是不容易出錯

  • 你不會通過您的二進制緩衝區作爲一個字符串函數,預計std::string錯誤

  • 可以覆蓋此類型的std::ostream<<()以正確的格式(通常是十六進制轉儲)打印blob。很可能你不想將二進制blob打印爲字符串。

還有更多。只有std::string的好處,我可以看到你不需要做typedef。