Farmland can end up scanning up to 162 blocks looking for water in the worst case. This is obviously not great for huge farms where there are thousands of blocks of the stuff.
In most farms, the water won't be moved, and nor will the farmland. This means that we can avoid this costly search on random updates.
This PR implements a cache using blockstate data (only possible in PM5) which stores an index mapping to a coordinate offset where water was previously found by this farmland block. This allows the farmland to avoid water searching entirely in most cases.
This is a colossal improvement as compared to scanning the whole 9x2x9 area every time, which, on average, scans about 40 blocks to find water if the water is at the same Y coordinate. In real terms this translates into about a 8x performance improvement for farmland (see timings below).
xxhash is generally well known for its hash key properties, so this is a suitable use case.
We XOR the state data with a partial hash of xxh3(typeID), which provides sufficient hash distribution regardless of the size of state data.
The previous method started to break down as the number of bits exceeded the number of significant bits of type ID (about 10 currently).
As well as being better for hash distribution regardless of state data size, this also reduces the load factor of RuntimeBlockRegistry to 1.08 (previously around 1.24), which is a nice bonus.
closes#6096
boundedIntAuto automatically calculates the correct number of bits to use based on the given bounds. The bounds must be constant, of course.
this makes it marginally faster, since we can skip all permutations containing invalid type data.
I measured a performance improvement of about 20% across all blocks.
In addition, this makes it easier to locate where a problem is coming from if invalid inputs are accepted.
This reverts commit 128eb500ebee5163583b84640a9c4f28c0218d42.
This breaks when entities in neighbouring chunks overlap into the
current chunk without actually being tracked by it.
Perhaps it might be worth having entities tracked by all chunks their
AABB touches in the future, so that we don't have to check padding
chunks and waste CPU time.
this slashes the cost of checking this with no entities by 50%, which should be the common case for farms and such.
once factoring in other things, this translates into a real-world performance gain of about 15% for block updates.
I'd prefer a smarter solution for this that automatically disables updates depending on which type of property was changed, but for now, this will significantly improve the performance of cactus farms.
The newly placed cactus block at the top cannot have updates disabled, though, since it needs to check its surroundings in case it grew into a space with a solid block next to it.
Thanks @KingOfTurkey38 for bringing this to light.
Track which direction the current node's light came from, and don't
check it again when we check the current node's adjacent blocks.
e.g. if this node was the eastern neighbour of a light source, we don't
need to check this node's western neighbour, as we already know it has
a higher light level than our own.
This improves performance of basic light spread in a void by about 6%,
which isn't a huge amount, but it's something.
I've yet to explore whether light removal could also benefit from this
change.
in many instances, remnants of improperly removed blocks from PM3 have been causing problems, such as flower pot tiles where there are no flower pots.
this change might break some plugins which are using tiles for custom purposes, but this is a misuse that was never supported properly in the first place.