Improve enhanced placed feature performance

This commit is contained in:
DBotThePony 2025-03-26 13:15:26 +07:00
parent e2369b3a24
commit 7a5a979169
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -3,13 +3,11 @@ package ru.dbotthepony.mc.otm.worldgen
import com.github.benmanes.caffeine.cache.Cache
import com.github.benmanes.caffeine.cache.Caffeine
import com.github.benmanes.caffeine.cache.Scheduler
import com.mojang.datafixers.util.Either
import com.mojang.datafixers.util.Pair
import com.mojang.serialization.Codec
import com.mojang.serialization.DataResult
import com.mojang.serialization.DynamicOps
import com.mojang.serialization.codecs.RecordCodecBuilder
import it.unimi.dsi.fastutil.ints.Int2ObjectRBTreeMap
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
import it.unimi.dsi.fastutil.objects.ObjectArrayList
import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet
import net.minecraft.Util
import net.minecraft.core.BlockPos
@ -23,15 +21,16 @@ import net.minecraft.world.level.levelgen.feature.Feature
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration
import net.minecraft.world.level.levelgen.placement.PlacedFeature
import net.minecraft.world.level.levelgen.placement.PlacementModifier
import ru.dbotthepony.kommons.util.XXHash64
import ru.dbotthepony.mc.otm.THREAD_LOCAL_RANDOM
import ru.dbotthepony.mc.otm.core.shuffle
import ru.dbotthepony.mc.otm.core.util.GJRAND64RandomSource
import ru.dbotthepony.mc.otm.data.codec.minRange
import ru.dbotthepony.mc.otm.worldgen.feature.EnhancedFeature
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedPlacement
import java.io.DataOutputStream
import java.time.Duration
import java.util.LinkedList
import java.util.*
import kotlin.math.sqrt
object EnhancedPlacedFeature : Feature<EnhancedPlacedFeature.Config>(
@ -137,7 +136,7 @@ object EnhancedPlacedFeature : Feature<EnhancedPlacedFeature.Config>(
fun place(context: FeaturePlaceContext<*>): Boolean {
val cache = getCache(context.level())
val chunkPos = ChunkPos(context.origin())
val instances = ArrayList<GeneratedChunk>()
val chunkPositions = ArrayList<ChunkPos>()
for (x in -chunkScanRange .. chunkScanRange) {
for (z in -chunkScanRange .. chunkScanRange) {
@ -146,13 +145,24 @@ object EnhancedPlacedFeature : Feature<EnhancedPlacedFeature.Config>(
if (radius <= chunkScanRange) {
val thisPos = ChunkPos(chunkPos.x + x, chunkPos.z + z)
instances.add(cache.get(thisPos) { evaluate(context, thisPos) })
chunkPositions.add(thisPos)
}
}
}
val withIndex = ObjectArrayList(chunkPositions.withIndex().iterator())
// evaluate chunks in random order, so in multithreaded environments we experience less congestion
// between threads which lookup cache while it is being populated on neighbouring chunks
withIndex.shuffle(THREAD_LOCAL_RANDOM)
val instances = Int2ObjectRBTreeMap<GeneratedChunk>()
withIndex.forEach { (i, it) ->
instances.put(i, cache.get(it) { evaluate(context, it) })
}
var any = false
instances.forEach { any = it.place(context) }
instances.values.forEach { any = it.place(context) }
return any
}
}