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 Issue #41

Closed
oloflarsson opened this issue Mar 1, 2014 · 1 comment
Closed

Performance Issue #41

oloflarsson opened this issue Mar 1, 2014 · 1 comment

Comments

@oloflarsson
Copy link

http://i.imgur.com/Lv41WRg.png

I use spigot and I set the entity tracking distance to 96 which is much higher than the default. I then get this performance issue when I have about 100 players on the same server.

@aadnk
Copy link
Owner

aadnk commented Mar 2, 2014

Are you using CPU sampling, by any chance? The number of invocations seems awfully low for 100 players, and it's very unlikely a simple method like getBukkitEntity() is going to require 291 ms per call. However, while instrumentation (see JProfiler) may be more accurate, it would probably cause too much overhead for a server with a 100 players.

In any case, I believe the issue here is that the number of transmitted packets grow exponentially when you increase the tracking distance. Imagine you set the tracking distance to 48 blocks (or meters), which is the default in Spigot, and 20 players are now within range of each other. This tracking distance forms a square (y direction is ignored) centered on each player, with a total area of (48+48)x(48+48) = 9216 m^2. Now, since each player must be notified of the presence, movement and state (potion effect, armor, etc.) of every other, you can expect at minimum 20 players * 19 recipients = 380 transmitted packets per state change.

Now, if you double the tracking distance to 96 m, the visible area for each player will be quadrupled, as the square increases to (96+96)x(96+96) = 36864 m^2. If we assume (for simplicity sake) that players are evenly distributed in the generated map, then our group of 20 players would grow to over 80 players (4 times). This in turn produces 6320 packets per state change, or 16.63 times as many as our group of 20 players.

In other words, doubling the tracking distance caused the number of packets to balloon to 16 times the original amount. Bear in mind, these are estimates, and players aren't usually distributed evenly. But that's actually the least disruptive possibility - if they're not distributed, some are bound to be closer to other players (usually in interesting areas, such as cities), and cause the number of packets to go up even higher for that cluster. Remember, the killer here is exponential growth.

You can work out the number of transmitted packet for entities as well, and find that it's increased by at least the square of the increase in tracking distance (4 times in your case). But, since the number of entities is much greater than the number of players, this is still a very significant increase.

And here's the kicker - every single one of those packets is inspected by LibsDisguise. Yes, unlike vanilla, where a broadcasted entity packet may only be constructed once, and then sent to a set of players, LibsDisguise has to take into account that each player may see a different disguise.

So, I don't think there's much I can do. Maybe I could optimize some reflection (or even avoid it, but that's unlikely), but I already employ a whole range of tricks for the sake of performance. Among other things, I generate classes for accessing packet fields, though that has been rendered obsolete in 1.7.2, seeing how nearly every packet field is now private or protected.

There's probably more to be gained by optimizing LibsDisguises. For instance, perhaps PacketsManager.transformPackets could be memorized on disguise and entity, to avoid having to process the same disguise multiple times. But I don't know how much that would actually save.

I still doubt if that would be enough to make performance acceptable in this case. The exponential increase of packet transmissions may just be too hard to deal with.

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

No branches or pull requests

3 participants