Skip to content

Commit

Permalink
Split the tickBlockEntities optimization into two patches
Browse files Browse the repository at this point in the history
  • Loading branch information
MrPowerGamerBR committed Nov 26, 2023
1 parent d8ba56e commit b82e107
Show file tree
Hide file tree
Showing 7 changed files with 330 additions and 267 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ SparklyPaper's config file is `sparklypaper.yml`, the file is, by default, place
* The `canSee(...)` checks is in a hot path (`ChunkMap#updatePlayers()`), invoked by each entity for each player on the server if they are in tracking range, so optimizing it is pretty nice.
* First, we change the original `HashMap` to fastutil's `Object2ObjectOpenHashMap`, because fastutil's `containsKey` throughput is better.
* Then, we add a `isEmpty()` check before attempting to check if the map contains something. This seems stupid, but it does seem that it improves the performance a bit, and it makes sense, `containsKey(...)` does not attempt to check the map size before attempting to check if the map contains the key.
* Optimize `tickBlockEntities`
* Fix `MC-117075`: TE Unload Lag Spike
* We replaced the `blockEntityTickers` list with a custom list based on fastutil's `ObjectArrayList` with a small yet huge change for us: A method that allows us to remove a list of indexes from the list.
* This is WAY FASTER than using `removeAll` with a list of entries to be removed, because we don't need to calculate the identity of each block entity to be removed, and we can jump directly to where the search should begin, giving a performance boost for small removals (because we don't need to loop thru the entire list to find what element should be removed) and a performance boost for big removals (no need to calculate the identity of each block entity).
* We also now cache the last `shouldTickBlocksAt` result, because the `shouldTickBlocksAt` is expensive because it requires pulling chunk holder info from an map for each block entity (even if the block entities are on the same chunk!) every single time. So, if the last chunk position is the same as our cached value, we use the last cached `shouldTickBlocksAt` result!
* This reverts a Paper patch with the same name, since both are editing the same section.
* Optimize `tickBlockEntities`
* We cache the last `shouldTickBlocksAt` result, because the `shouldTickBlocksAt` is expensive because it requires pulling chunk holder info from an map for each block entity (even if the block entities are on the same chunk!) every single time. So, if the last chunk position is the same as our cached value, we use the last cached `shouldTickBlocksAt` result!
* We could use a map for caching, but here's why this is way better than using a map: The block entity ticking list is sorted by chunks! Well, sort of... It is sorted by chunk when the chunk has been loaded, newly placed blocks will be appended to the end of the list until the chunk unloads and loads again. Most block entities are things that players placed to be there for a long time anyway (like hoppers, etc)
* But here's the thing: We don't care if we have a small performance penalty if the players have placed new block entities, the small performance hit of when a player placed new block entities is so small ('tis just a long comparsion after all), that the performance boost from already placed block entities is bigger, this helps a lot if your server has a lot of chunks with multiple block entities, and the block entities will be automatically sorted after the chunk is unloaded and loaded again, so it ain't that bad.
* And finally, we also cache the chunk's coordinate key when creating the block entity, which is actually "free" because we just reuse the already cached chunk coordinate key from the chunk!
Expand Down
257 changes: 0 additions & 257 deletions patches/server/0015-Optimize-tickBlockEntities.patch

This file was deleted.

Loading

0 comments on commit b82e107

Please sign in to comment.