2017-05-24 76 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。