The aquifer implementation currently tries to generate data for aquifers for every single block in the chunk, leading to the worldgen performance regression currently experienced in the 1.17 snapshots. By avoiding sampling aquifers in places where they cannot occur (i.e. above sea level) we can significantly improve performance. The change here is to skip the aquifer computation when above y30, as any position above y30 has a water level equal to the sea level. By skipping these checks we can avoid the expensive pressure and noise computation when we don't need it. The fix adds 1 to the current y level before getting the grid y to check further than the current position, and then subtracts 1 from the grid y to ensure the optimization can't affect water-air borders when entering a cave. The code for this is provided below:
int gridY = this.gridY(y + 1);
if ((gridY - 1) * 12 > 30) {
this.lastBarrierDensity = 0.0;
this.lastWaterLevel = this.noiseGeneratorSettings.seaLevel();
this.shouldScheduleWaterUpdate = false;
return;
}
This change would be placed at the top of Aquifer.computeAt. In addition, a second change could be made to Aquifer.computeAt to not allocate a new random instance every time the method is called. A final random field can be put into the aquifer class and the random construction can be replaced with the following to avoid object allocation, reducing the memory usage. Code below:
this.random.setSeed(Mth.getSeed(localX, localY * 3, localZ) + 1);
These changes were built upon changes created by @gegy1000 and are used with permission. We've licensed them as CC0. When profiling these changes while constantly generating chunks, the improved version took up 11% of the CPU usage compared to the 29% taken up prior to this change, which is a significant improvement and makes performance during world gen much better.
The y30 limit is temporary.