From c99404dfb0cfcad609f6cfed655ba4982f71f9ea Mon Sep 17 00:00:00 2001 From: ImplementsLegend Date: Wed, 25 Sep 2024 16:52:05 +0200 Subject: [PATCH] improved performance of WeightedListProcessor --- .../mod/vaultfaster/FastWeightedList.kt | 51 +++++++++++++++++++ .../mixin/MixinWeightedProcessor.java | 28 ++++++++++ src/main/resources/vaultfaster.mixins.json | 1 + 3 files changed, 80 insertions(+) create mode 100644 src/main/java/implementslegend/mod/vaultfaster/FastWeightedList.kt create mode 100644 src/main/java/implementslegend/mod/vaultfaster/mixin/MixinWeightedProcessor.java diff --git a/src/main/java/implementslegend/mod/vaultfaster/FastWeightedList.kt b/src/main/java/implementslegend/mod/vaultfaster/FastWeightedList.kt new file mode 100644 index 0000000..4b85555 --- /dev/null +++ b/src/main/java/implementslegend/mod/vaultfaster/FastWeightedList.kt @@ -0,0 +1,51 @@ +package implementslegend.mod.vaultfaster + +import iskallia.vault.core.random.RandomSource +import iskallia.vault.util.data.WeightedList +import java.util.random.RandomGenerator +import kotlin.random.Random + +class FastWeightedList private constructor(capacity:Int) { + + var totalWeight:Float = 0f + + var weights = FloatArray(capacity) + var values = ArrayList(capacity) + + val entries = weights.zip(values).filter { it.first!=0f } + + constructor(w:iskallia.vault.core.util.WeightedList):this(w.entries.size){ + w.entries.sortedBy { it.value }.forEach { + mutableEntry -> + totalWeight+=mutableEntry.value.toFloat() + values+=mutableEntry.key + weights[values.size-1]=mutableEntry.value.toFloat() + } + } + + + constructor(w:WeightedList):this(w.size){ + w.sortedBy { it.weight }.forEachIndexed { + index, mutableEntry -> + totalWeight+=mutableEntry.weight.toFloat() + weights[index]=mutableEntry.weight.toFloat() + values[index]=mutableEntry.value + } + } + + + fun random(rng:RandomGenerator) = random(rng::nextFloat) + fun random(rng:RandomSource) = random(rng::nextFloat) + fun random(rng:Random) = random(rng::nextFloat) + fun random(rng:()->Float):T?{ + if(totalWeight<=0f)return null + weights.foldIndexed(rng()*totalWeight){ + idx,acc,weight-> + if(acc cached; + + @Redirect(method = "process(Liskallia/vault/core/world/data/tile/PartialTile;Liskallia/vault/core/world/processor/ProcessorContext;)Liskallia/vault/core/world/data/tile/PartialTile;",at= @At(value = "INVOKE", target = "Liskallia/vault/core/util/WeightedList;getRandom(Liskallia/vault/core/random/RandomSource;)Ljava/util/Optional;"),remap = false) + private Optional fastRandom(WeightedList instance, RandomSource random){ + var list = cached; + if(list==null){ + list=new FastWeightedList<>(instance); + cached=list; + } + return Optional.ofNullable(list.random(random)); + } +} diff --git a/src/main/resources/vaultfaster.mixins.json b/src/main/resources/vaultfaster.mixins.json index 7796453..6dc7002 100644 --- a/src/main/resources/vaultfaster.mixins.json +++ b/src/main/resources/vaultfaster.mixins.json @@ -31,6 +31,7 @@ "MixinTemplate", "MixinTemplateProcessorModifier", "MixinVaultLayout", + "MixinWeightedProcessor", "NoBiomeDecorations", "OctahedralGroupFix", "PartialBlockIDAccessor",