Skip to content

Commit b53e5fa

Browse files
committed
micro-optimise TileComponentFrequency some more
1 parent 0601185 commit b53e5fa

File tree

2 files changed

+58
-19
lines changed

2 files changed

+58
-19
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package mekanism.common.lib;
2+
3+
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
4+
import it.unimi.dsi.fastutil.objects.ObjectSet;
5+
import it.unimi.dsi.fastutil.objects.ObjectSets;
6+
import java.util.Map;
7+
import java.util.function.BiConsumer;
8+
import org.jetbrains.annotations.NotNull;
9+
10+
/**
11+
* Version of array map which does a proper BiConsumer and a couple other microoptimisations.
12+
* Used in {@link mekanism.common.lib.frequency.TileComponentFrequency}, which is in a very hot path as EVERY mek machine uses one
13+
*/
14+
public class CustomObjectToObjectArrayMap<KEY, VALUE> extends Object2ObjectArrayMap<KEY, VALUE> {
15+
16+
public CustomObjectToObjectArrayMap() {
17+
super();
18+
}
19+
20+
public CustomObjectToObjectArrayMap(Map<? extends KEY, ? extends VALUE> m) {
21+
super(m);
22+
}
23+
24+
@SuppressWarnings("unchecked")
25+
@Override
26+
public void forEach(BiConsumer<? super KEY, ? super VALUE> consumer) {
27+
if (size == 0) {
28+
return;
29+
}
30+
final int max = size;
31+
for (int i = 0; i < max; i++) {
32+
consumer.accept((KEY)key[i], (VALUE)value[i]);
33+
}
34+
}
35+
36+
//save a tiny bit of heap space and not create an object
37+
@Override
38+
public @NotNull ObjectSet<KEY> keySet() {
39+
return size == 0 ? ObjectSets.emptySet() : super.keySet();
40+
}
41+
42+
//save a tiny bit of heap space and not create an object
43+
@Override
44+
public @NotNull ObjectSet<Map.Entry<KEY, VALUE>> entrySet() {
45+
return size == 0 ? ObjectSets.emptySet() : super.entrySet();
46+
}
47+
}

src/main/java/mekanism/common/lib/frequency/TileComponentFrequency.java

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
import com.mojang.datafixers.util.Pair;
44
import com.mojang.serialization.DataResult;
55
import com.mojang.serialization.DynamicOps;
6-
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
76
import java.util.ArrayList;
8-
import java.util.Collections;
97
import java.util.EnumMap;
108
import java.util.LinkedHashMap;
119
import java.util.List;
@@ -15,13 +13,15 @@
1513
import java.util.Set;
1614
import java.util.UUID;
1715
import java.util.concurrent.atomic.AtomicInteger;
16+
import java.util.function.BiConsumer;
1817
import java.util.function.Consumer;
1918
import mekanism.api.SerializationConstants;
2019
import mekanism.api.security.SecurityMode;
2120
import mekanism.common.attachments.FrequencyAware;
2221
import mekanism.common.inventory.container.MekanismContainer;
2322
import mekanism.common.inventory.container.sync.SyncableFrequency;
2423
import mekanism.common.inventory.container.sync.list.SyncableFrequencyList;
24+
import mekanism.common.lib.CustomObjectToObjectArrayMap;
2525
import mekanism.common.lib.frequency.Frequency.FrequencyIdentity;
2626
import mekanism.common.lib.security.SecurityFrequency;
2727
import mekanism.common.lib.security.SecurityUtils;
@@ -49,7 +49,7 @@ public class TileComponentFrequency implements ITileComponent {
4949

5050
private final TileEntityMekanism tile;
5151

52-
private Map<FrequencyType<?>, FrequencyData> nonSecurityFrequencies = Collections.emptyMap();
52+
private final CustomObjectToObjectArrayMap<FrequencyType<?>, FrequencyData> nonSecurityFrequencies = new CustomObjectToObjectArrayMap<>();
5353
@Nullable
5454
private FrequencyData securityFrequency = null;
5555

@@ -59,6 +59,9 @@ public class TileComponentFrequency implements ITileComponent {
5959
private boolean needsSave;
6060
private boolean needsNotify;
6161

62+
//Method refs to allocate once and reuse in hot path
63+
private final BiConsumer<FrequencyType<?>, FrequencyData> updateFrequencyRef = this::updateFrequency;
64+
6265
public TileComponentFrequency(TileEntityMekanism tile) {
6366
this.tile = tile;
6467
this.tickOffset = OFFSET.getAndIncrement() % 5;
@@ -78,9 +81,7 @@ public void tickServer(Level level, BlockPos pos) {
7881
if (securityFrequency != null) {
7982
updateFrequency(FrequencyType.SECURITY, securityFrequency);
8083
}
81-
for (Entry<FrequencyType<?>, FrequencyData> entry : nonSecurityFrequencies.entrySet()) {
82-
updateFrequency(entry.getKey(), entry.getValue());
83-
}
84+
nonSecurityFrequencies.forEach(updateFrequencyRef);
8485
}
8586
if (needsNotify) {
8687
tile.invalidateCapabilitiesFull();
@@ -101,15 +102,7 @@ public void track(FrequencyType<?> type, boolean needsSync, boolean needsListCac
101102
if (type == FrequencyType.SECURITY) {
102103
securityFrequency = value;
103104
} else {
104-
if (nonSecurityFrequencies.isEmpty()) {
105-
nonSecurityFrequencies = Collections.singletonMap(type, value);
106-
} else if (nonSecurityFrequencies.size() == 1) {
107-
//don't expect this to happen, unless we get an all-in-one block
108-
nonSecurityFrequencies = new Object2ObjectArrayMap<>(nonSecurityFrequencies);
109-
nonSecurityFrequencies.put(type, value);
110-
} else {
111-
nonSecurityFrequencies.put(type, value);
112-
}
105+
nonSecurityFrequencies.put(type, value);
113106
}
114107
}
115108

@@ -266,8 +259,8 @@ public String getComponentKey() {
266259
@Override
267260
public void applyImplicitComponents(@NotNull BlockEntity.DataComponentInput input) {
268261
if (!tile.isRemote()) {
269-
for (Map.Entry<FrequencyType<?>, FrequencyData> entry : nonSecurityFrequencies.entrySet()) {
270-
setFrequencyFromComponent(input, entry.getKey());
262+
for (FrequencyType<?> key : nonSecurityFrequencies.keySet()) {
263+
setFrequencyFromComponent(input, key);
271264
}
272265
}
273266
}
@@ -286,8 +279,7 @@ private <FREQ extends Frequency> void setFrequencyFromComponent(BlockEntity.Data
286279

287280
@Override
288281
public void addRemapEntries(List<DataComponentType<?>> remapEntries) {
289-
for (Map.Entry<FrequencyType<?>, FrequencyData> entry : nonSecurityFrequencies.entrySet()) {
290-
FrequencyType<?> type = entry.getKey();
282+
for (FrequencyType<?> type : nonSecurityFrequencies.keySet()) {
291283
DataComponentType<? extends FrequencyAware<?>> frequencyComponent = MekanismDataComponents.getFrequencyComponent(type);
292284
if (frequencyComponent != null && !remapEntries.contains(frequencyComponent)) {
293285
remapEntries.add(frequencyComponent);

0 commit comments

Comments
 (0)