Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance optimization of chat #3634

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

Janmm14
Copy link
Contributor

@Janmm14 Janmm14 commented Mar 15, 2024

  1. Add lazy json deserialization of chat content (until BaseComponent is questioned, save only String/Tag).
    To achieve this, a Deserializable interface has been added with a few implementations. Existing getters, setters and constructors have been kept as they were, added are new "raw" versions of it, exposing the Deserializable itself.

These performance optimizations are based on the assumption that most plugins and use cases do not involve reading mc-server-sent chat/tablist header/footer/entries inside bungeecord.

Basic testing has been done.

@Janmm14
Copy link
Contributor Author

Janmm14 commented Mar 15, 2024

I changed a little compared to chat-optimzation-v2.

Better javadoc on Deserializable
Replaced Suppliers with captured original value to Functions which get original value via parameter

@Janmm14 Janmm14 changed the title Optimize chat Performance optimization of chat Mar 15, 2024
@andreasdc
Copy link

andreasdc commented Mar 15, 2024

Bukkit servers don't send this in json already? If yes, can't it be used?

@Janmm14
Copy link
Contributor Author

Janmm14 commented Mar 15, 2024

Bukkit servers don't send this in json already? If yes, can't it be used?

Thats what this pr does. It keeps the json string unless basecomponent requested by other code or a setter used to override.

In newer versions, they do not send json string, but they send nbt. In that case, this PR will omit the conversion of nbt to json, but due to nbt having no size prefix, it needs to read the bytes into nbt.

@andreasdc
Copy link

Sounds great. 😎 🚀

@andreasdc
Copy link

andreasdc commented Mar 18, 2024

java.lang.NullPointerException: Cannot invoke "net.md_5.bungee.protocol.Deserializable.get()" because "this.displayNameRaw" is null
on this line


Maybe I messed something up, I'm not sure. It happens with BungeeTabListPlus.
Maybe it should be like that, I did that and there's no error.

BTW I guess this patch won't help with BTLP?

@Janmm14
Copy link
Contributor Author

Janmm14 commented Mar 18, 2024

java.lang.NullPointerException: Cannot invoke "net.md_5.bungee.protocol.Deserializable.get()" because "this.displayNameRaw" is null on this line

Maybe I messed something up, I'm not sure. It happens with BungeeTabListPlus.
Maybe it should be like that, I did that and there's no error.

BTW I guess this patch won't help with BTLP?

Nice catch, your correction looks correct.

@Janmm14
Copy link
Contributor Author

Janmm14 commented Mar 18, 2024

Fixed the same thing in other places. And yes, this patch likely does not help performance of bungeetablistplus.

@andreasdc
Copy link

I'm testing this in production, other that the error that I sent you I don't see any problems. Here are the profilers, I think the performance is better. :)
https://i.imgur.com/fC3RwL1.png
image
image

@Janmm14
Copy link
Contributor Author

Janmm14 commented Mar 28, 2024

Fixed stupid mistake in writeBaseComponenet Janmm14@e275e38
Squashig commits.

Tested basic functionality.

md-5 pushed a commit that referenced this pull request Mar 30, 2024
md-5 pushed a commit that referenced this pull request Mar 30, 2024
Stop use of subclass for static method call.
Make test helper methods static.
@md-5
Copy link
Member

md-5 commented Mar 30, 2024

Can you please merge/rebase the remaining?

Thanks

@Janmm14
Copy link
Contributor Author

Janmm14 commented Mar 31, 2024

@md-5 I was able to just cherry-pick the missing main commit 8cd1505 onto master?!

@md-5
Copy link
Member

md-5 commented Mar 31, 2024

Thanks

@@ -0,0 +1,28 @@
package net.md_5.bungee.protocol;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these new classes should go in a separate package (util or otherwise)

@@ -18,7 +22,7 @@ public class BossBar extends DefinedPacket

private UUID uuid;
private int action;
private BaseComponent title;
private Deserializable<Either<String, SpecificTag>, BaseComponent> title;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think every instance is "Deserializable<Either<String, SpecificTag>, BaseComponent>", so we should probably create a helper "ChatDeserializable extends Deserializable<Either<String, SpecificTag>, BaseComponent>"

Copy link
Contributor Author

@Janmm14 Janmm14 Apr 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating a ChatDeserializable is unfortunaly not working as an alias and would require all implementations to be doubled.
If you want it shorter, the solution I see is to get rid of generics and just start worrying about extendability and code reuse if we actually need it at some later point.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a tough one. Maybe leave Deserializable and specialise the implementations?

@@ -163,6 +164,16 @@ public static String toString(Object object)
return gson.toJson( object );
}

public static String toString(Content content)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for these being added?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During work on this, I noticed #3629 and wanted to remove any invocations of toString(Object), and here I jsut forgot to mention it.
I would further suggest to deprecate the toString(Object) method here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added deprecation

@Janmm14 Janmm14 force-pushed the optimize-chat branch 4 times, most recently from 6cb2be9 to 0f23c99 Compare April 14, 2024 18:11
@Janmm14
Copy link
Contributor Author

Janmm14 commented Apr 14, 2024

Fcking import order

@Janmm14
Copy link
Contributor Author

Janmm14 commented Apr 18, 2024

Please do another review.

@bob7l
Copy link
Contributor

bob7l commented Apr 19, 2024

Hopefully, this gets merged. It will set a precedent for future packet decoding/handling as well. The serialization/deserialization process is likely only going to become more complex/heavy with each new Minecraft version release.

@Janmm14
Copy link
Contributor Author

Janmm14 commented Apr 21, 2024

Hopefully, this gets merged. It will set a precedent for future packet decoding/handling as well. The serialization/deserialization process is likely only going to become more complex/heavy with each new Minecraft version release.

Just some offtopic chatting:
General packet handling/decoding in bungee already keeps the serialized ByteBuf for decoded packets if they are not changed (changing requires to throw cancelsendsignal in handler and re-send).

Other proposed speedups in packet handling code are:

@Janmm14
Copy link
Contributor Author

Janmm14 commented Apr 21, 2024

thxrben pushed a commit to thxrben/BungeeCord that referenced this pull request Jun 16, 2024
thxrben pushed a commit to thxrben/BungeeCord that referenced this pull request Jun 16, 2024
Stop use of subclass for static method call.
Make test helper methods static.
@andreasdc
Copy link

1.21 update? 🚀 Also I don't have any problems with this patch, I think it should be implemented. 🔥

@bob7l
Copy link
Contributor

bob7l commented Jun 20, 2024

1.21 update? 🚀 Also I don't have any problems with this patch, I think it should be implemented. 🔥

I agree it should be implemented too, but it's going to be very plugin-breaking. A plugin using the BossBar packet for instance, the methods get/set#BaseComponent would no longer exist due to the wrapper replacing the BaseComponent obviously.

So it wouldn't be a quick and painless merge. Will require a large amount of plugins to update.

@andreasdc
Copy link

andreasdc commented Jun 20, 2024

1.21 update? 🚀 Also I don't have any problems with this patch, I think it should be implemented. 🔥

I agree it should be implemented too, but it's going to be very plugin-breaking. A plugin using the BossBar packet for instance, the methods get/set#BaseComponent would no longer exist due to the wrapper replacing the BaseComponent obviously.

So it wouldn't be a quick and painless merge. Will require a large amount of plugins to update.

There may be workarounds and plugin authors can update their projects, these classes received updates not so long time ago anyway.

@Janmm14
Copy link
Contributor Author

Janmm14 commented Jun 20, 2024

1.21 update? 🚀 Also I don't have any problems with this patch, I think it should be implemented. 🔥

I agree it should be implemented too, but it's going to be very plugin-breaking. A plugin using the BossBar packet for instance, the methods get/set#BaseComponent would no longer exist due to the wrapper replacing the BaseComponent obviously.

So it wouldn't be a quick and painless merge. Will require a large amount of plugins to update.

Packets / protocol is not official part of the API.
An earlier version of this had backwards support, but md-5 did not want it.

@Janmm14
Copy link
Contributor Author

Janmm14 commented Jun 20, 2024

Updated for 1.21 with rebase

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants