【问题标题】:Java - Object Stream efficiency over networkJava - 网络上的对象流效率
【发布时间】:2011-12-21 13:19:27
【问题描述】:

快速设计问题:我需要在我的游戏引擎架构中实现客户端-服务器网络之间的一种通信形式,以便在彼此之间发送事件。

我选择创建事件对象,因此,我想知道将这些对象序列化并通过简单套接字网络通过对象流传递它们的效率如何?

也就是说,与创建对象的字符串表示、通过字符流发送字符串以及解析字符串客户端相比,效率如何?

事件将在每个游戏循环中发送,如果不是更多的话;但事件对象本身只是一些 java 原语的简单包装。

感谢您的洞察!

(tl;dr - 网络上的对象流高效吗?)

【问题讨论】:

  • 我建议启动一份 Wireshark (wireshark.org) 并测试自己。

标签: java networking java-io


【解决方案1】:

如果性能是主要问题,我建议在您自己的自定义序列化和 Java 的本机序列化中使用 Protocol Buffers

Jon Skeet 在这里给出了很好的解释和基准:High performance serialization: Java vs Google Protocol Buffers vs ...?

如果你不能使用 PB,我怀疑 Java 的本机序列化将比从 String 手动序列化/反序列化更优化。这种差异是否显着可能取决于您要序列化的对象的复杂程度。与往常一样,您应该进行基准测试以确认您的预测。

您通过网络发送东西的事实应该无关紧要。

【讨论】:

    【解决方案2】:

    编辑:对于时间要求严格的应用程序,Protocol Buffers 似乎是更好的选择。但是,在我看来,开发时间显着增加。实际上,您必须对每条交换消息进行两次编码:一次作为 .proto 文件,该文件被编译并吐出 java 包装器,一次作为 POJO,它使这些包装器变得有用。但这是从文档中猜测的。
    编辑结束

    摘要:寻找对象流

    那么,什么是少?对对象进行编码、发送字节流并对其进行解码所需的时间 - 全部手动 - 还是对对象进行编码、发送字节流和解码所需的时间 - 全部由可靠且经过尝试的序列化机制完成?

    您应该确保您发送的对象尽可能小。这可以在可能的情况下通过枚举值、查找表等来实现。每次传输可能会减少几个字节。序列化算法对我来说似乎非常快,你编写的任何代码都会做同样的事情。当你重新发明轮子时,往往会得到三角形。

    【讨论】:

    • 一旦性能(或小序列化大小)很重要,使用本机 Java 实现总是错误的决定,真的。无论如何,Protobuf 并不复杂,提供跨语言支持,而且速度更快。如果带有 java 实习生的序列化需要 40 毫秒而 protobuf 在 中完成,这甚至都不好笑
    • @Voo 40ms 是真实测量的数字吗?
    • 现在已经查看了 ProtoBuf 文档。太糟糕了,当我在九个月前建立通信基础设施时,这会很有用。照原样,本机序列化就像一个魅力,并且对于我的目的来说足够快(序列化的往返时间约为 50-100 毫秒,发送到 LAN 中的服务器,反序列化,服务器端处理,重新序列化和发回给所有客户)。可能为 WAN 行程增加几十毫秒,对于大多数应用程序来说,你的速度已经足够快了。
    • @EJP 是的,显然不是一条消息,而是 100k 或更多消息。您的里程可能会有所不同,但假设平均性能差异至少为 1:10 似乎是合理的 - 而且可能会更糟。 See here for official benchmarks
    • @MikeAdler 不是。您创建 .proto 文件,ProtoBuf 编译器会自动为您生成正确的类。 ProtoBuf 和序列化之间的唯一区别是,一个使用简单的字节流,另一个使用 ObjectStream。如果您有现有的类,则基本上必须更改您的 getter/setter 以处理生成的文件(即,而不是 getX() {return x;} 我们得到 getX() {return storage.x;} 或其他东西)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-07
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多