Port optimizations

This commit is contained in:
IzzelAliz 2021-02-04 18:52:38 +08:00
parent 403536e754
commit 24db9e1cc0
10 changed files with 371 additions and 5 deletions

View File

@ -12,6 +12,10 @@ import java.util.function.Supplier;
@Mixin(PacketDistributor.class)
public class PacketDistributorMixin {
/**
* @author IzzelAliz
* @reason
*/
@Overwrite(remap = false)
private Consumer<IPacket<?>> playerConsumer(Supplier<ServerPlayerEntity> entityPlayerMPSupplier) {
return p -> {

View File

@ -81,6 +81,8 @@ dependencies {
embed 'net.md-5:bungeecord-chat:1.16-R0.4@jar'
embed "org.spigotmc:spigot-api:$minecraftVersion-R0.1-SNAPSHOT@jar"
embed 'com.github.ArclightTeam:mixin-tools:1.0.0@jar'
annotationProcessor 'org.spongepowered:mixin:0.8.2:processor'
annotationProcessor 'com.github.ArclightTeam:mixin-tools:1.0.0'
}
def getGitHash = { ->
@ -121,7 +123,7 @@ remapSpigotJar {
}
mixin {
// add sourceSets.main, 'mixins.arclight.impl.refmap.1_15.json'
add sourceSets.main, 'mixins.arclight.impl.refmap.1_16.json'
}
compileJava {

View File

@ -1,6 +1,8 @@
package io.izzel.arclight.impl;
import io.izzel.arclight.common.mod.ArclightConnector;
import io.izzel.arclight.i18n.ArclightConfig;
import org.spongepowered.asm.mixin.Mixins;
@SuppressWarnings("unused")
public class ArclightConnector_1_16 extends ArclightConnector {
@ -8,10 +10,10 @@ public class ArclightConnector_1_16 extends ArclightConnector {
@Override
public void connect() {
super.connect();
/*
Mixins.addConfiguration("mixins.arclight.impl.optimization.1_16.json");
if (ArclightConfig.spec().getOptimization().isRemoveStream()) {
Mixins.addConfiguration("mixins.arclight.impl.optimization.stream.1_15.json");
Mixins.addConfiguration("mixins.arclight.impl.optimization.stream.1_16.json");
}
LOGGER.info("mixin-load.optimization");*/
LOGGER.info("mixin-load.optimization");
}
}

View File

@ -0,0 +1,127 @@
package io.izzel.arclight.impl.common.optimization;
import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
import it.unimi.dsi.fastutil.doubles.DoubleList;
import net.minecraft.util.math.shapes.IDoubleListMerger;
import org.jetbrains.annotations.NotNull;
/**
* @author jellysquid3 (LGPLv3)
*/
public class OptimizedIndirectMerger implements IDoubleListMerger {
private final double[] merged;
private final int[] indicesFirst;
private final int[] indicesSecond;
private final DoubleArrayList pairs;
public OptimizedIndirectMerger(DoubleList aPoints, DoubleList bPoints, boolean flag1, boolean flag2) {
double[] araw;
if (aPoints instanceof DoubleArrayList) {
araw = ((DoubleArrayList) aPoints).elements();
} else {
araw = new double[aPoints.size()];
for (int i = 0; i < araw.length; i++) {
araw[i] = aPoints.getDouble(i);
}
}
double[] braw;
if (bPoints instanceof DoubleArrayList) {
braw = ((DoubleArrayList) bPoints).elements();
} else {
braw = new double[bPoints.size()];
for (int i = 0; i < braw.length; i++) {
braw[i] = bPoints.getDouble(i);
}
}
int size = araw.length + braw.length;
this.merged = new double[size];
this.indicesFirst = new int[size];
this.indicesSecond = new int[size];
this.pairs = DoubleArrayList.wrap(this.merged);
this.merge(araw, braw, araw.length, braw.length, flag1, flag2);
}
private void merge(double[] aPoints, double[] bPoints, int aSize, int bSize, boolean flag1, boolean flag2) {
int aIdx = 0;
int bIdx = 0;
double prev = 0.0D;
int a1 = 0, a2 = 0;
while (true) {
boolean aWithinBounds = aIdx < aSize;
boolean bWithinBounds = bIdx < bSize;
if (!aWithinBounds && !bWithinBounds) {
break;
}
boolean flip = aWithinBounds && (!bWithinBounds || aPoints[aIdx] < bPoints[bIdx] + 1.0E-7D);
double value;
if (flip) {
value = aPoints[aIdx++];
} else {
value = bPoints[bIdx++];
}
if ((aIdx == 0 || !aWithinBounds) && !flip && !flag2) {
continue;
}
if ((bIdx == 0 || !bWithinBounds) && flip && !flag1) {
continue;
}
if (a2 == 0 || prev < value - 1.0E-7D) {
this.indicesFirst[a1] = aIdx - 1;
this.indicesSecond[a1] = bIdx - 1;
this.merged[a2] = value;
a1++;
a2++;
prev = value;
} else if (a2 > 0) {
this.indicesFirst[a1 - 1] = aIdx - 1;
this.indicesSecond[a1 - 1] = bIdx - 1;
}
}
if (a2 == 0) {
this.merged[a2++] = Math.min(aPoints[aSize - 1], bPoints[bSize - 1]);
}
this.pairs.size(a2);
}
@Override
public @NotNull DoubleList func_212435_a() {
return this.pairs;
}
@Override
public boolean forMergedIndexes(@NotNull IConsumer consumer) {
int l = this.pairs.size() - 1;
for (int i = 0; i < l; i++) {
if (!consumer.merge(this.indicesFirst[i], this.indicesSecond[i], i)) {
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,51 @@
package io.izzel.arclight.impl.mixin.optimization.general;
import net.minecraft.util.ClassInheritanceMultiMap;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@Mixin(ClassInheritanceMultiMap.class)
public class ClassInheritanceMultiMapMixin<T> {
// @formatter:off
@Shadow @Final private Class<T> baseClass;
@Shadow @Final private Map<Class<?>, List<T>> map;
@Shadow @Final private List<T> values;
// @formatter:on
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
public <S> Collection<S> getByClass(Class<S> p_219790_1_) {
Collection<T> collection = this.map.get(p_219790_1_);
if (collection == null) {
collection = this.createList(p_219790_1_);
}
return (Collection<S>) Collections.unmodifiableCollection(collection);
}
private <S> Collection<T> createList(Class<S> p_219790_1_) {
if (!this.baseClass.isAssignableFrom(p_219790_1_)) {
throw new IllegalArgumentException("Don't know how to search for " + p_219790_1_);
} else {
List<T> list = new ArrayList<>();
for (T value : this.values) {
if (p_219790_1_.isInstance(value)) {
list.add(value);
}
}
this.map.put(p_219790_1_, list);
return list;
}
}
}

View File

@ -0,0 +1,19 @@
package io.izzel.arclight.impl.mixin.optimization.general;
import io.izzel.arclight.impl.common.optimization.OptimizedIndirectMerger;
import it.unimi.dsi.fastutil.doubles.DoubleList;
import net.minecraft.util.math.shapes.IDoubleListMerger;
import net.minecraft.util.math.shapes.VoxelShapes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(VoxelShapes.class)
public class VoxelShapesMixin {
@Inject(method = "makeListMerger", at = @At(value = "NEW", target = "net/minecraft/util/math/shapes/IndirectMerger", shift = At.Shift.BEFORE), cancellable = true)
private static void arclight$optimizedMerger(int p_199410_0_, DoubleList list1, DoubleList list2, boolean p_199410_3_, boolean p_199410_4_, CallbackInfoReturnable<IDoubleListMerger> cir) {
cir.setReturnValue(new OptimizedIndirectMerger(list1, list2, p_199410_3_, p_199410_4_));
}
}

View File

@ -0,0 +1,111 @@
package io.izzel.arclight.impl.mixin.optimization.stream;
import net.minecraft.entity.ai.goal.Goal;
import net.minecraft.entity.ai.goal.GoalSelector;
import net.minecraft.entity.ai.goal.PrioritizedGoal;
import net.minecraft.profiler.IProfiler;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Stream;
@Mixin(GoalSelector.class)
public abstract class GoalSelectorMixin {
// @formatter:off
@Shadow @Final private Set<PrioritizedGoal> goals;
@Shadow @Final private Supplier<IProfiler> profiler;
@Shadow public abstract Stream<PrioritizedGoal> getRunningGoals();
@Shadow @Final private EnumSet<Goal.Flag> disabledFlags;
@Shadow @Final private Map<Goal.Flag, PrioritizedGoal> flagGoals;
@Shadow @Final private static PrioritizedGoal DUMMY;
// @formatter:on
/**
* @author IzzelAliz
* @reason optimization
*/
@Overwrite
public void removeGoal(Goal task) {
for (Iterator<PrioritizedGoal> iterator = this.goals.iterator(); iterator.hasNext(); ) {
PrioritizedGoal goal = iterator.next();
if (goal.getGoal() == task) {
if (goal.isRunning()) {
goal.resetTask();
}
iterator.remove();
}
}
}
/**
* @author IzzelAliz
* @reason optimization
*/
@Overwrite
public void tick() {
IProfiler iprofiler = this.profiler.get();
iprofiler.startSection("goalCleanup");
for (PrioritizedGoal prioritizedGoal : this.goals) {
if (prioritizedGoal.isRunning()) {
EnumSet<Goal.Flag> flags = this.disabledFlags;
boolean b = false;
for (Goal.Flag flag : prioritizedGoal.getMutexFlags()) {
if (flags.contains(flag)) {
b = true;
break;
}
}
if (!prioritizedGoal.isRunning() || b || !prioritizedGoal.shouldContinueExecuting()) {
prioritizedGoal.resetTask();
}
}
}
for (Iterator<Map.Entry<Goal.Flag, PrioritizedGoal>> iterator = this.flagGoals.entrySet().iterator(); iterator.hasNext(); ) {
Map.Entry<Goal.Flag, PrioritizedGoal> entry = iterator.next();
PrioritizedGoal p_220885_2_ = entry.getValue();
if (!p_220885_2_.isRunning()) {
iterator.remove();
}
}
iprofiler.endSection();
iprofiler.startSection("goalUpdate");
for (PrioritizedGoal goal : this.goals) {
if (!goal.isRunning()) {
EnumSet<Goal.Flag> flags = this.disabledFlags;
boolean b = true;
for (Goal.Flag flag1 : goal.getMutexFlags()) {
if (flags.contains(flag1) || !this.flagGoals.getOrDefault(flag1, DUMMY).isPreemptedBy(goal)) {
b = false;
break;
}
}
if (b) {
if (goal.shouldExecute()) {
for (Goal.Flag flag : goal.getMutexFlags()) {
PrioritizedGoal prioritizedgoal = this.flagGoals.getOrDefault(flag, DUMMY);
prioritizedgoal.resetTask();
this.flagGoals.put(flag, goal);
}
goal.startExecuting();
}
}
}
}
iprofiler.endSection();
iprofiler.startSection("goalTick");
for (PrioritizedGoal goal : this.goals) {
if (goal.isRunning()) {
goal.tick();
}
}
iprofiler.endSection();
}
}

View File

@ -0,0 +1,30 @@
package io.izzel.arclight.impl.mixin.optimization.stream;
import net.minecraft.util.concurrent.ITaskQueue;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import java.util.List;
import java.util.Queue;
@Mixin(ITaskQueue.Priority.class)
public class ITaskQueue_PriorityMixin {
@Shadow @Final private List<Queue<Runnable>> queues;
/**
* @author IzzelAliz
* @reason optimization
*/
@Overwrite
public boolean isEmpty() {
for (Queue<Runnable> queue : this.queues) {
if (!queue.isEmpty()) {
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,10 @@
{
"minVersion": "0.8",
"package": "io.izzel.arclight.impl.mixin.optimization.general",
"target": "@env(DEFAULT)",
"refmap": "mixins.arclight.impl.refmap.1_16.json",
"mixins": [
"ClassInheritanceMultiMapMixin",
"VoxelShapesMixin"
]
}

View File

@ -0,0 +1,10 @@
{
"minVersion": "0.8",
"package": "io.izzel.arclight.impl.mixin.optimization.stream",
"target": "@env(DEFAULT)",
"refmap": "mixins.arclight.impl.refmap.1_16.json",
"mixins": [
"GoalSelectorMixin",
"ITaskQueue_PriorityMixin"
]
}