Unity-Technologies / Unity-Technologies/com.unity.netcode.gameobjects

Named Messages: Don't allocate a byte array whenever you send a message

未关闭
#2,779 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

type:feature
主要语言
C#
星标
2.3k
派生
461
平均合并
3 天 16 小时
30 天内合并 PR
20

描述

Is your feature request related to a problem? Please describe.
Named Messages are a great way to send custom messages that are not tied to a specific game object and/or are more dynamic than standard RPC calls. However, the only way to send these messages (via CustomMessagingManager.SendNamedMessage) is by providing a string which gets then hashed using XXHash.Hash32 or XXHash.Hash64 which then calls Encoding.UTF8.GetBytes(text). This function always allocates a new byte array, containing the string. As far as I can see, there is no other possible way to send a named message.

Describe the solution you'd like
I see two possible solutions:

  • Don't use Encoding.UTF8.GetBytes(text) and instead use one of the overloads where you can specify an existing byte[] or Span. This would allow the use of a pre-alloced buffer (e.g. from a temp alloced NativeArray or an array pool).
  • Add a function overload where I can provide the hash myself (and provide a way to obtain this hash). This would work similar to e.g. Animator.StringToHash or Shader.PropertyToID. However, the HashSize can be 4 bytes or 8 bytes (depending on NetworkManager.NetworkConfig.RpcHashSize) and can even change during the runtime (at least, CustomMessageManager supports this case). Therefore it might be a bit confusing to the user which hash (with which data type) they have to use in this case - unless the GetHash function returns a struct which contains both hashes...which might be a bit weird as well.

Describe alternatives you've considered

  • I can use unnamed messages and just re-implement the logic from named messages, using the solution described above.

Additional context

Example GC Alloc from the profiler:

Size: 41

Call Stack:
mscorlib.dll!System.Text::Encoding.GetBytes()
Unity.Netcode.Runtime.dll!Unity.Netcode::XXHash.Hash32()	./Library/PackageCache/com.unity.netcode.gameobjects@1.5.2/Runtime/Hashing/XXHash.cs:218
Unity.Netcode.Runtime.dll!Unity.Netcode::CustomMessagingManager.SendNamedMessage()	./Library/PackageCache/com.unity.netcode.gameobjects@1.5.2/Runtime/Messaging/CustomMessageManager.cs:296
Unity.Netcode.Runtime.dll!Unity.Netcode::CustomMessagingManager.SendNamedMessageToAll()	./Library/PackageCache/com.unity.netcode.gameobjects@1.5.2/Runtime/Messaging/CustomMessageManager.cs:236

I wouldn't say this is a huge problem (though it depends on how many messages are being sent and how long their name is), and unnamed messages are an easy workaround. However, most of this package seems to focus on allocating as little as possible, and I think that fixing this problem here shouldn't be too hard (otherwise just ignore this issue).

Thanks for your work on this amazing package, I really enjoy using it! I can also provide a PR with a fix mentioned above if you would like me to, I just didn't want to submit something unwanted.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

首先阅读 Runtime/Hashing/XXHash.cs 和 Runtime/Messaging/CustomMessageManager.cs,尤其是 SendNamedMessage 的调用路径,以及报告行中指出的分配。使用 profiler 重现命名消息的分配,然后确定如何在配置的哈希大小发生变化时,同时保留 32 位和 64 位哈希行为并避免该分配。完成的标准是:命名发送不再分配名称字节数组,并且现有行为仍由可用的测试覆盖。

由索引模型根据 Issue 内容生成。

评估

技术栈
csharp, unity
领域
networking, performance
Issue 类型
功能
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
38/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。