Closed Ghost-chu closed 8 months ago
I have put this PR in draft status and we are applying this change from the test environment to the production environment. This PR status will be updated once we confirm that the change is not causing issues.
I am certain that this patch improves performance and does not introduce compelling issues. It works fine on a production environment.
Status | Compare Image |
---|---|
Before | |
After |
Here we go!
Thanks! Didn't know that Inventory.getHolder() was so expensive.
I guess we can't just always return inventory.getLocation().getBlock()
(with added null check) because of chest minecarts and other entities? But I see a problem here, as minecarts with chest also have the CHEST inventory type.
I'll have a look at it tomorrow.
Thanks! Didn't know that Inventory.getHolder() was so expensive.
I guess we can't just always return
inventory.getLocation().getBlock()
(with added null check) because of chest minecarts and other entities? But I see a problem here, as minecarts with chest also have the CHEST inventory type.I'll have a look at it tomorrow.
I also noticed the Minecart issue when I was modifying this part of the code, but it seems that BlockLocker doesn't deal with it in the first place (Minecart can't be protected by Sign). I also tested the Hopper Minecart and was unable to remove items from protected containers.
Then I might as well always return the block at the inventory, no matter what. 🙂
I've merged your pull request, thanks!
Performance improvements
I've observed BlockLocker-induced performance degradation on our servers.
The method
getInventoryBlockOrNull(Inventory)
attempts to acquire the InventoryHolder on each call, and this behavior indirectly creates a new BlockState capture on the block.What's worse, however, is that this method is called repeatedly every tick, by the large number of Hoppers running on the server. And Hopper Minecart makes it even worse.
This PR checks the type of the requested Inventory. A fast algorithm is applied to the InventoryType that is not in COMPLEX_SEARCH_INVENTORY list. The unique Block object is returned directly from the Inventory's Location.
Also, for inventory that are in the COMPLEX_SEARCH_INVENTORY list, a quick double-chest check is performed, and if it's not a possible double-chest, we use the same quick algorithm as for the other InventoryTypes, and just return the Block object obtained by Location.
For Double-Chest, they use the same algorithms as in the past, and currently the Bukkit API still doesn't have a good interface to handle them efficiently.
Crafter
Minor change to add Crafter to the default list.