传输原始数据,例如 int、float-tuple:解析字符串或转换为字节数组更有效?

Posted

技术标签:

【中文标题】传输原始数据,例如 int、float-tuple:解析字符串或转换为字节数组更有效?【英文标题】:Transmitting primitive data such as an int,float-tuple: More efficient to parse strings or convert to byte array? 【发布时间】:2018-10-20 01:11:58 【问题描述】:

在执行大量 MapReduce 操作时,我希望传输的数据开销尽可能小。我目前需要传输很多东西之一是 (int,float) 元组等。我目前正在尝试在两种传输方式之间进行选择:

    序列化为字符串,例如“4,3.4”。如果我使用 ASCII-US,我猜传输对象的大小将只是字符串形式所需的字符数量,即如果我的整数很长或者我的浮点数很精确,那么对象可能会变得很大。

    序列化为字节数组:int 使用 4 个字节,float 使用 4 个字节。这样我就一直使用 8 个字节。在特殊情况下,我可能会少用字符串,但我猜字符串方式平均会更贵。

因此,我目前倾向于第二个选项,虽然转换比仅序列化为字符串稍微复杂一些,但它应该更有效,对吧?

【问题讨论】:

【参考方案1】:

这是一个相当复杂的问题。

一方面,将数字从二进制形式转换为文本形式……然后再转换回来,计算成本(相对)昂贵。转换为十进制特别昂贵,因为转换涉及重复除/乘以 10。

另一方面,如果数据值(平均)较小,则文本表示在编码时可能(平均)占用更少的字节。根据您的网络(包括 NIC、虚拟化等)的端到端速度和延迟,较小的在线表示可能会导致更高的吞吐量。

另一方面,如果通信成本在整个计算中只是微不足道的一部分,这将是没有意义的。

我的建议是:

    提防过早的优化! 在您的环境中对编码 + 传输 + 解码的两种备选方案(二进制和文本)进行基准测试。请确保您使用的测试数据将是您的实际数据的典型数据。 对整个应用程序进行基准测试。 (这假设您注意了第一点!) 确定二进制与文本表示的差异是否会对完整应用程序在真实数据上的整体性能产生显着差异。 重新编写代码...如果您的测量结果等告诉您这将是值得的。

注意:如果测量结果告诉您二进制与文本之间的差异对您的应用程序而言实际上很重要,则可能表明您的计算在通信与计算方面花费了太多时间。看看你是否可以减少数量的交流是值得的;例如通过更改计算的粒度或移动的数据量。


终于……

在执行大量 MapReduce 操作时,我希望传输的数据开销尽可能小。

这不应该是你的目标。真正的目标应该是:

使应用程序作为一个整体运行得足够快以满足性能要求。 优化开发人员时间,不要试图实现超过实际要求的性能。

诸如“尽可能快”、“尽可能高效”或“尽可能小”之类的目标可能是危险的努力下降。你应该尽量避免它们。

【讨论】:

没错,我倾向于忘记过早优化是万恶之源,哈哈。谢谢你的回答!【参考方案2】:

您可以使用ASCII或UTF-8格式将数据转换为字节。

只需将字符串转换为字节数组并将格式作为 ASCII/UTF-8 传递 我会推荐 UTF-8,因为它支持比 ASCII 更多的特殊字符。

String s = "some text here";
byte[] b = s.getBytes("UTF-8");

通过反序列化,您可以轻松地将字节数组转换为字符串。

【讨论】:

以上是关于传输原始数据,例如 int、float-tuple:解析字符串或转换为字节数组更有效?的主要内容,如果未能解决你的问题,请参考以下文章

原始类型包装器

盒装与原始类型作为实体 id

Integer与int的区别

从原始数据就地创建 std::vector

些许细节

int 和 Integer 的区别