当做很多MapReduce操作时,我希望传输的数据有尽可能少的开销。我目前需要传输很多的东西之一是(int,float(元组等。我目前正在尝试在两种传输方式之间进行选择:
-
序列化为字符串,例如"4,3.4"。如果我使用 ASCII-US,我猜测传输对象的大小只是字符串形式所需的字符数量,即如果我的整数很长或我的浮点数很精确,对象可能会变得很大。
-
序列化为字节数组:对 int 使用 4 个字节,对浮点数使用 4 个字节。这样我就会一直使用 8 个字节。在特殊情况下,我可能会少用字符串,但我猜字符串方式平均会更昂贵。
因此,我目前倾向于第二种选择,尽管转换比序列化为字符串稍微复杂一些,但它应该更有效,对吧?
这是一个相当复杂的问题。
-
一方面,将数字从二进制转换为文本形式(相对(计算成本很高......然后回来。 转换为十进制特别昂贵,因为转换涉及重复除法/乘以 10。
-
另一方面,如果数据值(平均(很小,则文本表示在编码时可能(平均(占用较少的字节。 根据网络的端到端速度和延迟(包括 NIC、虚拟化等(,较小的在线表示可能会导致更大的吞吐量。
-
第三,如果通信费用在整个计算中是微不足道的一部分,这将毫无意义。
我的建议是:
- 当心过早优化!
- 对环境中编码 + 传输 + 解码的两种替代方法(二进制和文本(进行基准测试。 请确保使用实际数据的典型测试数据执行此操作。 对
- 整个应用程序进行基准测试。 (这假设你注意了第一点!
- 确定二进制表示形式与文本表示形式的差异是否会对完整应用程序在实际数据上的整体性能产生显著影响。
- 返工代码...如果您的测量等告诉您,那么值得付出努力。
注意:如果测量告诉你二进制与文本之间的差异实际上对你的应用程序很重要,这可能表明你的计算花费了太多时间进行通信和计算。 值得一看的是,您是否可以减少沟通量;例如,通过更改计算的粒度或正在移动的数据量。
最后。。。
在执行大量MapReduce操作时,我希望传输的数据具有尽可能少的开销。
这不应该是你的目标。 目标应该是:
- 使整个应用程序作为一个足够快的速度来满足性能要求。
- 通过不尝试实现超出实际要求的性能来优化开发人员时间。
像"尽可能快"或"尽可能高效"或"尽可能小"这样的目标可能是危险的努力下沉。 你应该尽量避免它们。
您可以通过使用 ASCII 或 UTF-8 格式进行转换将数据转换为字节。
只需将字符串转换为字节数组并将格式传递为 ASCII/UTF-8 我推荐 UTF-8,因为它将支持比 ASCII 更多的特殊字符。
String s = "some text here";
byte[] b = s.getBytes("UTF-8");
通过反序列化,您可以轻松地将字节数组转换为字符串。