Hidendra / LWC

Lightweight Protection for Chests, Furnaces, Dispensers, and more for the Minecraft server mod Bukkit
Other
167 stars 123 forks source link

Magnet task (item pick-up by chests) causes extreme lag #441

Open bergerkiller opened 11 years ago

bergerkiller commented 11 years ago

See here: https://github.com/Hidendra/LWC/blob/master/src/main/java/com/griefcraft/modules/flag/MagnetModule.java#L86

This task is gathering a loooot of items. If you have more than 6000 items on the server, this is causing a lot of tick lag. I recommend you put this item 'detecting' in another thread instead. The same I had to do in NoLagg's item stacker; all entities are put into a list, another thread operates on this list and matches the items in range. This data is packed and then a synchronized task operates on the items to stack them. In your case, it would put them into the chest inventory.

Also be aware that you are calling getItemStack() on every single item. Don't do this. This creates a new instance in memory which contains a lot of data. (Enchantments NBT tag being a major problem). Instead, try to use native calls to directly interact with the native itemstack and compare it this way. This causes a 30 m/s memory usage rate at some point, though I'm not entirely sure this was the cause.

Especially 'scan for inventory blocks' causes a lot of lag when a lot of items are involved. It is a recursive block operation creating, again, a lot of block instances. The many world access (getTypeId) causes a slow processing as well. Instead of using a recursive operation, try to obtain all tile entities (again, native code...) instead. This allows you to instantly obtain all the chests, furnaces and etc on the WORLD.

Please look into this ASAP. (this entire issue is to compensate for the 'I have lag' issues here - this is the lag everyone is having)

(Lag that is occurring: Every 50 ticks there is a lag spike which depends on how many items are there)

Opening magnet.yml and setting enabled: to false disables this feature and gets rid of the lag as well.

Hidendra commented 11 years ago

Especially 'scan for inventory blocks' causes a lot of lag when a lot of items are involved. It is a recursive block operation creating, again, a lot of block instances.

Done. Better than a db call at least ;)

Also be aware that you are calling getItemStack() on every single item. Don't do this. This creates a new instance in memory which contains a lot of data.

Looking at CB's source the only overhead appears to be enchantments (the overhead of adding CraftItemStack is negligible) since it rebuilds the enchantments every time. And like you say, a lot of temporary memory.

I will see about looking into this one next.

This task is gathering a loooot of items. If you have more than 6000 items on the server, this is causing a lot of tick lag. I recommend you put this item 'detecting' in another thread instead.

Given the large dependency on world based code (scanning for items, scanning for blocks that can be used, depositing items, dropping items in the world) I'm not sure how this could be done without a lot of code and not very much benefit.

If this is definitely an issue after optimizing the other issues then it could be something I would look into :) The biggest issue seems to be scanning n * (2r)^3 (n=pickupable items, r=radius) blocks which should be good now.

Hidendra commented 11 years ago

Also be aware that you are calling getItemStack() on every single item. Don't do this. This creates a new instance in memory which contains a lot of data.

Done.

Could you please see if you are still seeing tick lag in Jenkins build #775 I'm not really able to reproduce this hence why I've not done anything beforehand.

Hidendra commented 11 years ago

I will be working on converting the magnet task to async today