Preffered way of looping through blocks in area

Hi, I am developing a plugin and one of the things it has to do is periodically loop though all blocks in the area and count them (has to be specific counting algorithm so I cannot user third-party tools like worledit API for the counting). Since it has to be done every few minutes and it will be done on multiple areas, I want to have the best performance and ideally not lag server too much. So what is preferred and most efficient way of looping blocks in specific area? Also is viable to do async count for each area that I have to count, or it is better to do it synchronously?

Currently I am using this approach:

Extent view = world.getExtentView(lowerCorner, higherCorner);
int sum = view.getBlockWorker(Cause.of(NamedCause.of("plugin", plugin))).reduce(
    (vol, x, y, z, count) -> {
     // Counting algorithm
    },
    (a, b) -> a + b,
     0);

Using the block worker is in no way faster then just looping manually. It could be done in parallel, but that isn’t implemented right now. If your region is small, your current approach is fine.
If the region gets larger, you’ll want to use view.getImmutableBlockCopy() to obtain a copy of the region. That copy can then safely be used in an asynchronous task without blocking the main server thread.

2 Likes

Thank you very much :slight_smile:

I’d consider counting once, then keeping track using events in order to minimize the amount of times you need to count.

Also, if possible split it into multiple smaller areas, and do those checks more often in order to spread the computation around. I’d suggest potentially doing it async, but considering that an immutable copy would need to be made, and all you need to do is count, that might end up using more performance depending on exactly how the copy routines work.

2 Likes