diff --git a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index df135a9a..d48b970e 100644 --- a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -32,6 +32,7 @@ public class ModernFixEarlyConfig { this.addMixinRule("perf.preload_block_classes", false); this.addMixinRule("perf.parallel_potentially_unsafe", false); this.addMixinRule("perf.parallel_blockstate_cache_rebuild", true); + this.addMixinRule("perf.deduplicate_location", true); this.addMixinRule("safety", true); this.addMixinRule("launch.transformer_cache", false); this.addMixinRule("launch.class_search_cache", false); diff --git a/src/main/java/org/embeddedt/modernfix/dedup/DeduplicationCache.java b/src/main/java/org/embeddedt/modernfix/dedup/DeduplicationCache.java new file mode 100644 index 00000000..d31cd53e --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/dedup/DeduplicationCache.java @@ -0,0 +1,56 @@ +package org.embeddedt.modernfix.dedup; + +import it.unimi.dsi.fastutil.Hash; +import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; + +import java.util.Objects; + +public class DeduplicationCache { + private final ObjectOpenCustomHashSet pool; + + private int attemptedInsertions = 0; + private int deduplicated = 0; + + public DeduplicationCache(Hash.Strategy strategy) { + this.pool = new ObjectOpenCustomHashSet<>(strategy); + } + + public DeduplicationCache() { + this.pool = new ObjectOpenCustomHashSet<>(new Hash.Strategy() { + @Override + public int hashCode(T o) { + return Objects.hashCode(o); + } + + @Override + public boolean equals(T a, T b) { + return Objects.equals(a, b); + } + }); + } + + public synchronized T deduplicate(T item) { + this.attemptedInsertions++; + + T result = this.pool.addOrGet(item); + + if (result != item) { + this.deduplicated++; + } + + return result; + } + + public synchronized void clearCache() { + this.attemptedInsertions = 0; + this.deduplicated = 0; + + this.pool.clear(); + } + + @Override + public synchronized String toString() { + return String.format("DeduplicationCache ( %d/%d de-duplicated, %d pooled )", + this.deduplicated, this.attemptedInsertions, this.pool.size()); + } +} diff --git a/src/main/java/org/embeddedt/modernfix/dedup/IdentifierCaches.java b/src/main/java/org/embeddedt/modernfix/dedup/IdentifierCaches.java new file mode 100644 index 00000000..b34ef714 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/dedup/IdentifierCaches.java @@ -0,0 +1,15 @@ +package org.embeddedt.modernfix.dedup; + + +import org.embeddedt.modernfix.ModernFix; + +public class IdentifierCaches { + public static final DeduplicationCache NAMESPACES = new DeduplicationCache<>(); + public static final DeduplicationCache PATH = new DeduplicationCache<>(); + + public static void printDebug() { + ModernFix.LOGGER.info("[[[ Identifier de-duplication statistics ]]]"); + ModernFix.LOGGER.info("Namespace cache: {}", NAMESPACES); + ModernFix.LOGGER.info("Path cache: {}", PATH); + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/deduplicate_location/MixinResourceLocation.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/deduplicate_location/MixinResourceLocation.java new file mode 100644 index 00000000..7a67de59 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/deduplicate_location/MixinResourceLocation.java @@ -0,0 +1,30 @@ +package org.embeddedt.modernfix.mixin.perf.deduplicate_location; + +import net.minecraft.util.ResourceLocation; +import org.embeddedt.modernfix.dedup.IdentifierCaches; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ResourceLocation.class) +public class MixinResourceLocation { + @Mutable + @Shadow + @Final + protected String namespace; + + @Mutable + @Shadow + @Final + protected String path; + + @Inject(method = "([Ljava/lang/String;)V", at = @At("RETURN")) + private void reinit(String[] id, CallbackInfo ci) { + this.namespace = IdentifierCaches.NAMESPACES.deduplicate(this.namespace); + this.path = IdentifierCaches.PATH.deduplicate(this.path); + } +} diff --git a/src/main/resources/modernfix.mixins.json b/src/main/resources/modernfix.mixins.json index 8b96d2d3..e8e6b565 100644 --- a/src/main/resources/modernfix.mixins.json +++ b/src/main/resources/modernfix.mixins.json @@ -24,7 +24,8 @@ "perf.parallel_blockstate_cache_rebuild.BlocksMixin", "perf.parallel_blockstate_cache_rebuild.BlockCallbacksMixin", "perf.parallel_blockstate_cache_rebuild.ShapeCacheMixin", - "perf.parallel_potentially_unsafe.parallel_deferred_suppliers.DispenserBlockMixin" + "perf.parallel_potentially_unsafe.parallel_deferred_suppliers.DispenserBlockMixin", + "perf.deduplicate_location.MixinResourceLocation" ], "client": [ "perf.skip_first_datapack_reload.MinecraftMixin",