From b6e689314b2ec9c2d62e4d532c125d2fd879df8b Mon Sep 17 00:00:00 2001 From: TeamDman <TeamDman9201@gmail.com> Date: Mon, 7 Oct 2024 00:34:14 -0400 Subject: [PATCH] performance optimization --- .../common/program/IInputResourceTracker.java | 10 ++++--- .../program/IOutputResourceTracker.java | 10 ++++--- ...mulateExploreAllPathsProgramBehaviour.java | 6 ++-- .../ca/teamdman/sfml/ast/InputStatement.java | 30 +++++++++---------- .../ca/teamdman/sfml/ast/OutputStatement.java | 23 +++++++------- .../teamdman/sfml/ast/ResourceComparer.java | 2 +- .../ca/teamdman/sfml/ast/ResourceIdSet.java | 18 +++++------ .../teamdman/sfml/ast/ResourceIdentifier.java | 5 ++-- .../ca/teamdman/sfml/ast/ResourceLimits.java | 15 +++++----- 9 files changed, 57 insertions(+), 62 deletions(-) diff --git a/src/main/java/ca/teamdman/sfm/common/program/IInputResourceTracker.java b/src/main/java/ca/teamdman/sfm/common/program/IInputResourceTracker.java index b863e83cc..7a52880b0 100644 --- a/src/main/java/ca/teamdman/sfm/common/program/IInputResourceTracker.java +++ b/src/main/java/ca/teamdman/sfm/common/program/IInputResourceTracker.java @@ -55,9 +55,11 @@ default boolean matchesStack(Object stack) { } default boolean matchesCapabilityType(Object capability) { - return getResourceLimit() - .resourceIds() - .getReferencedResourceTypes() - .anyMatch(rt -> rt.matchesCapabilityType(capability)); + for (ResourceType<?, ?, ?> resourceType : getResourceLimit().resourceIds().getReferencedResourceTypes()) { + if (resourceType.matchesCapabilityType(capability)) { + return true; + } + } + return false; } } diff --git a/src/main/java/ca/teamdman/sfm/common/program/IOutputResourceTracker.java b/src/main/java/ca/teamdman/sfm/common/program/IOutputResourceTracker.java index fbc077025..5999cc67a 100644 --- a/src/main/java/ca/teamdman/sfm/common/program/IOutputResourceTracker.java +++ b/src/main/java/ca/teamdman/sfm/common/program/IOutputResourceTracker.java @@ -31,10 +31,12 @@ <STACK, ITEM, CAP> long getMaxTransferable( ); default boolean matchesCapabilityType(Object capability) { - return getResourceLimit() - .resourceIds() - .getReferencedResourceTypes() - .anyMatch(rt -> rt.matchesCapabilityType(capability)); + for (ResourceType<?, ?, ?> resourceType : getResourceLimit().resourceIds().getReferencedResourceTypes()) { + if (resourceType.matchesCapabilityType(capability)) { + return true; + } + } + return false; } default boolean matchesStack(Object stack) { diff --git a/src/main/java/ca/teamdman/sfm/common/program/SimulateExploreAllPathsProgramBehaviour.java b/src/main/java/ca/teamdman/sfm/common/program/SimulateExploreAllPathsProgramBehaviour.java index 25daf03d6..7cac99ac7 100644 --- a/src/main/java/ca/teamdman/sfm/common/program/SimulateExploreAllPathsProgramBehaviour.java +++ b/src/main/java/ca/teamdman/sfm/common/program/SimulateExploreAllPathsProgramBehaviour.java @@ -11,7 +11,6 @@ import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collectors; import java.util.stream.Stream; public class SimulateExploreAllPathsProgramBehaviour implements ProgramBehaviour { @@ -182,11 +181,10 @@ public record Branch( ) implements ExecutionPathElement { } - @SuppressWarnings("rawtypes") public record IO( IOStatement statement, IOKind kind, - Set<ResourceType> usedResourceTypes, + Set<ResourceType<?,?,?>> usedResourceTypes, Set<Label> usedLabels ) implements ExecutionPathElement { public IO(IOStatement statement) { @@ -196,7 +194,7 @@ public IO(IOStatement statement) { statement instanceof InputStatement ? IOKind.INPUT : (statement instanceof OutputStatement ? IOKind.OUTPUT : null), - statement.resourceLimits().getReferencedResourceTypes().collect(Collectors.toSet()), + statement.resourceLimits().getReferencedResourceTypes(), new HashSet<>(statement.labelAccess().labels()) ); if (kind == null) { diff --git a/src/main/java/ca/teamdman/sfml/ast/InputStatement.java b/src/main/java/ca/teamdman/sfml/ast/InputStatement.java index 87720e0dd..e230ee8b0 100644 --- a/src/main/java/ca/teamdman/sfml/ast/InputStatement.java +++ b/src/main/java/ca/teamdman/sfml/ast/InputStatement.java @@ -7,7 +7,10 @@ import net.minecraft.core.Direction; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayDeque; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -75,31 +78,26 @@ public void gatherSlots( }; } - // identify distinct resource types for capability gathering - Set<ResourceType> referencedResourceTypes = resourceLimits - .getReferencedResourceTypes() - .collect(Collectors.toSet()); - if (!each) { // log not each context.getLogger().debug(x -> x.accept(LOG_PROGRAM_TICK_IO_STATEMENT_GATHER_SLOTS_NOT_EACH.get())); // create a single matcher to be shared by all capabilities List<IInputResourceTracker> inputTrackers = resourceLimits.createInputTrackers(); - for (var type : referencedResourceTypes) { + for (var resourceType : resourceLimits.getReferencedResourceTypes()) { // log gather for resource type context .getLogger() .debug(x -> x.accept(LOG_PROGRAM_TICK_IO_STATEMENT_GATHER_SLOTS_FOR_RESOURCE_TYPE.get( - type.displayAsCapabilityClass(), - type.displayAsCapabilityClass() + resourceType.displayAsCapabilityClass(), + resourceType.displayAsCapabilityClass() ))); // gather slots for each capability found for positions tagged by a provided label Consumer<LimitedInputSlot<?, ?, ?>> finalSlotConsumer = slotConsumer; - type.forEachCapability(context, labelAccess, (label, pos, direction, cap) -> gatherSlotsForCap( + resourceType.forEachCapability(context, labelAccess, (label, pos, direction, cap) -> gatherSlotsForCap( context, - (ResourceType<Object, Object, Object>) type, + (ResourceType<Object, Object, Object>) resourceType, label, pos, direction, cap, inputTrackers, finalSlotConsumer @@ -109,22 +107,22 @@ public void gatherSlots( // log yes each context.getLogger().debug(x -> x.accept(LOG_PROGRAM_TICK_IO_STATEMENT_GATHER_SLOTS_EACH.get())); - for (ResourceType type : referencedResourceTypes) { + for (var resourceType : resourceLimits.getReferencedResourceTypes()) { // log gather for resource type context .getLogger() .debug(x -> x.accept(LOG_PROGRAM_TICK_IO_STATEMENT_GATHER_SLOTS_FOR_RESOURCE_TYPE.get( - type.displayAsCapabilityClass(), - type.displayAsCapabilityClass() + resourceType.displayAsCapabilityClass(), + resourceType.displayAsCapabilityClass() ))); // gather slots for each capability found for positions tagged by a provided label Consumer<LimitedInputSlot<?, ?, ?>> finalSlotConsumer = slotConsumer; - type.forEachCapability(context, labelAccess, (label, pos, direction, cap) -> { + resourceType.forEachCapability(context, labelAccess, (label, pos, direction, cap) -> { List<IInputResourceTracker> inputTrackers = resourceLimits.createInputTrackers(); gatherSlotsForCap( context, - (ResourceType<Object, Object, Object>) type, + (ResourceType<Object, Object, Object>) resourceType, label, pos, direction, cap, inputTrackers, finalSlotConsumer diff --git a/src/main/java/ca/teamdman/sfml/ast/OutputStatement.java b/src/main/java/ca/teamdman/sfml/ast/OutputStatement.java index 9d92c86ae..43f549543 100644 --- a/src/main/java/ca/teamdman/sfml/ast/OutputStatement.java +++ b/src/main/java/ca/teamdman/sfml/ast/OutputStatement.java @@ -13,7 +13,6 @@ import java.util.Objects; import java.util.function.Consumer; import java.util.stream.Collectors; -import java.util.stream.Stream; import static ca.teamdman.sfm.common.localization.LocalizationKeys.*; @@ -346,23 +345,21 @@ public void gatherSlots( ) { context.getLogger().debug(x -> x.accept(LOG_PROGRAM_TICK_IO_STATEMENT_GATHER_SLOTS.get(toStringPretty()))); - Stream<ResourceType> types = resourceLimits.getReferencedResourceTypes(); - if (!each) { context.getLogger().debug(x -> x.accept(LOG_PROGRAM_TICK_IO_STATEMENT_GATHER_SLOTS_NOT_EACH.get())); // create a single list of trackers to be shared between all limited slots List<IOutputResourceTracker> outputTracker = resourceLimits.createOutputTrackers(); - for (var type : (Iterable<ResourceType>) types::iterator) { + for (var resourceType : resourceLimits.getReferencedResourceTypes()) { context .getLogger() .debug(x -> x.accept(LOG_PROGRAM_TICK_IO_STATEMENT_GATHER_SLOTS_FOR_RESOURCE_TYPE.get( - type.displayAsCapabilityClass(), - type.displayAsCapabilityClass() + resourceType.displayAsCapabilityClass(), + resourceType.displayAsCapabilityClass() ))); - type.forEachCapability(context, labelAccess, ( + resourceType.forEachCapability(context, labelAccess, ( (label, pos, direction, cap) -> gatherSlotsForCap( context, - (ResourceType<Object, Object, Object>) type, + (ResourceType<Object, Object, Object>) resourceType, label, pos, direction, @@ -374,19 +371,19 @@ public void gatherSlots( } } else { context.getLogger().debug(x -> x.accept(LOG_PROGRAM_TICK_IO_STATEMENT_GATHER_SLOTS_EACH.get())); - for (var type : (Iterable<ResourceType>) types::iterator) { + for (var resourceType : resourceLimits.getReferencedResourceTypes()) { context .getLogger() .debug(x -> x.accept(LOG_PROGRAM_TICK_IO_STATEMENT_GATHER_SLOTS_FOR_RESOURCE_TYPE.get( - type.displayAsCapabilityClass(), - type.displayAsCapabilityClass() + resourceType.displayAsCapabilityClass(), + resourceType.displayAsCapabilityClass() ))); - type.forEachCapability(context, labelAccess, (label, pos, direction, cap) -> { + resourceType.forEachCapability(context, labelAccess, (label, pos, direction, cap) -> { // create a new list of trackers for each limited slot List<IOutputResourceTracker> outputTracker = resourceLimits.createOutputTrackers(); gatherSlotsForCap( context, - (ResourceType<Object, Object, Object>) type, + (ResourceType<Object, Object, Object>) resourceType, label, pos, direction, diff --git a/src/main/java/ca/teamdman/sfml/ast/ResourceComparer.java b/src/main/java/ca/teamdman/sfml/ast/ResourceComparer.java index 118ad1e3c..69c20b520 100644 --- a/src/main/java/ca/teamdman/sfml/ast/ResourceComparer.java +++ b/src/main/java/ca/teamdman/sfml/ast/ResourceComparer.java @@ -24,7 +24,7 @@ public BoolExpr toBooleanExpression(SetOperator setOp, LabelAccess labelAccess, type.forEachCapability(context, labelAccess, (label, pos, direction, cap) -> { long inThisInv = 0; for (var stack : (Iterable<STACK>) type.getStacksInSlots(cap, labelAccess.slots())::iterator) { - if (this.res.test(stack)) { + if (this.res.matchesStack(stack)) { inThisInv += type.getAmount(stack); overallCount.addAndGet(type.getAmount(stack)); } diff --git a/src/main/java/ca/teamdman/sfml/ast/ResourceIdSet.java b/src/main/java/ca/teamdman/sfml/ast/ResourceIdSet.java index eb9e4b7db..c62a281c1 100644 --- a/src/main/java/ca/teamdman/sfml/ast/ResourceIdSet.java +++ b/src/main/java/ca/teamdman/sfml/ast/ResourceIdSet.java @@ -4,10 +4,7 @@ import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -24,11 +21,12 @@ public ResourceIdSet(Collection<ResourceIdentifier<?, ?, ?>> contents) { this(new LinkedHashSet<>(contents)); } - @SuppressWarnings("rawtypes") - public Stream<ResourceType> getReferencedResourceTypes() { // todo: cache maybe? check perf - return this.stream() - .map((ResourceIdentifier x) -> x.getResourceType()) - .distinct(); + public Set<ResourceType<?,?,?>> getReferencedResourceTypes() { + HashSet<ResourceType<?,?,?>> rtn = new HashSet<>(8); + for (ResourceIdentifier<?, ?, ?> resourceId : this.resourceIds) { + rtn.add(resourceId.getResourceType()); + } + return rtn; } public boolean couldMatchMoreThanOne() { @@ -51,7 +49,7 @@ public ResourceIdSet( public @Nullable ResourceIdentifier<?, ?, ?> getMatchingFromStack(Object stack) { for (ResourceIdentifier<?, ?, ?> entry : resourceIds) { - if (entry.test(stack)) { + if (entry.matchesStack(stack)) { return entry; } } diff --git a/src/main/java/ca/teamdman/sfml/ast/ResourceIdentifier.java b/src/main/java/ca/teamdman/sfml/ast/ResourceIdentifier.java index 1ba5e06a3..84da51d2a 100644 --- a/src/main/java/ca/teamdman/sfml/ast/ResourceIdentifier.java +++ b/src/main/java/ca/teamdman/sfml/ast/ResourceIdentifier.java @@ -17,7 +17,7 @@ // resourceTypeName resourceNamespace, resourceTypeName name, resource resourceNamespace, resource name // sfm:item:minecraft:stone -public class ResourceIdentifier<STACK, ITEM, CAP> implements ASTNode, Predicate<Object> { +public class ResourceIdentifier<STACK, ITEM, CAP> implements ASTNode { public static final ResourceIdentifier<?, ?, ?> MATCH_ALL = new ResourceIdentifier<>( ".*", @@ -111,8 +111,7 @@ public Optional<ResourceLocation> getLocation() { } } - @Override - public boolean test(Object other) { + public boolean matchesStack(Object other) { ResourceType<STACK, ITEM, CAP> resourceType = getResourceType(); return resourceType != null && resourceType.matchesStack(this, other); } diff --git a/src/main/java/ca/teamdman/sfml/ast/ResourceLimits.java b/src/main/java/ca/teamdman/sfml/ast/ResourceLimits.java index 14b89b5c5..1ede4b192 100644 --- a/src/main/java/ca/teamdman/sfml/ast/ResourceLimits.java +++ b/src/main/java/ca/teamdman/sfml/ast/ResourceLimits.java @@ -5,9 +5,10 @@ import ca.teamdman.sfm.common.resourcetype.ResourceType; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.Stream; public record ResourceLimits( List<ResourceLimit> resourceLimitList, @@ -36,12 +37,12 @@ public ResourceLimits withExclusions(ResourceIdSet exclusions) { return new ResourceLimits(resourceLimitList, exclusions); } - @SuppressWarnings("rawtypes") - public Stream<ResourceType> getReferencedResourceTypes() { - return resourceLimitList() - .stream() - .flatMap(resourceLimits -> resourceLimits.resourceIds().getReferencedResourceTypes()) - .distinct(); + public Set<ResourceType<?,?,?>> getReferencedResourceTypes() { + Set<ResourceType<?,?,?>> rtn = new HashSet<>(8); + for (ResourceLimit resourceLimit : resourceLimitList) { + rtn.addAll(resourceLimit.resourceIds().getReferencedResourceTypes()); + } + return rtn; } @Override