mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-02-13 01:20:04 +00:00
Clean up the wired network tests
- Replace usages of WiredNetwork.connect/disconnect/remove with the WiredNode equivalents. - Convert "testLarge" into a proper JMH benchmark. - Don't put a peripheral on every node in the benchmarks. This isn't entirely representative, and means the peripheral juggling code ends up dominating the benchmark time.
This commit is contained in:
parent
a0f759527d
commit
2d11b51c62
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,6 +9,7 @@
|
||||
/projects/*/logs
|
||||
/projects/fabric/fabricloader.log
|
||||
/projects/*/build
|
||||
/projects/*/src/test/generated_tests/
|
||||
/buildSrc/build
|
||||
/out
|
||||
/buildSrc/out
|
||||
|
@ -51,6 +51,7 @@ sodium = "mc1.20-0.4.10"
|
||||
hamcrest = "2.2"
|
||||
jqwik = "1.8.2"
|
||||
junit = "5.10.1"
|
||||
jmh = "1.37"
|
||||
|
||||
# Build tools
|
||||
cctJavadoc = "1.8.2"
|
||||
@ -127,6 +128,8 @@ junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.re
|
||||
junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" }
|
||||
junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit" }
|
||||
slf4j-simple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" }
|
||||
jmh = { module = "org.openjdk.jmh:jmh-core", version.ref = "jmh" }
|
||||
jmh-processor = { module = "org.openjdk.jmh:jmh-generator-annprocess", version.ref = "jmh" }
|
||||
|
||||
# LWJGL
|
||||
lwjgl-bom = { module = "org.lwjgl:lwjgl-bom", version.ref = "lwjgl" }
|
||||
|
@ -46,6 +46,9 @@ dependencies {
|
||||
testImplementation(libs.bundles.test)
|
||||
testRuntimeOnly(libs.bundles.testRuntime)
|
||||
|
||||
testImplementation(libs.jmh)
|
||||
testAnnotationProcessor(libs.jmh.processor)
|
||||
|
||||
testModCompileOnly(libs.mixin)
|
||||
testModImplementation(testFixtures(project(":core")))
|
||||
testModImplementation(testFixtures(project(":common")))
|
||||
|
@ -0,0 +1,183 @@
|
||||
// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers
|
||||
//
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package dan200.computercraft.impl.network.wired;
|
||||
|
||||
import dan200.computercraft.api.network.wired.WiredNetwork;
|
||||
import dan200.computercraft.impl.network.wired.NetworkTest.NetworkElement;
|
||||
import dan200.computercraft.shared.util.DirectionUtil;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
import org.openjdk.jmh.runner.Runner;
|
||||
import org.openjdk.jmh.runner.RunnerException;
|
||||
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
public class NetworkBenchmark {
|
||||
private static final int BRUTE_SIZE = 16;
|
||||
|
||||
public static void main(String[] args) throws RunnerException {
|
||||
var opts = new OptionsBuilder()
|
||||
.include(NetworkBenchmark.class.getName() + "\\..*")
|
||||
.warmupIterations(2)
|
||||
.measurementIterations(5)
|
||||
.forks(1)
|
||||
.build();
|
||||
new Runner(opts).run();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@Warmup(time = 1, timeUnit = TimeUnit.SECONDS)
|
||||
@Measurement(time = 2, timeUnit = TimeUnit.SECONDS)
|
||||
public void removeEveryNode(ConnectedGrid grid) {
|
||||
grid.grid.forEach((node, pos) -> node.remove());
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@Warmup(time = 1, timeUnit = TimeUnit.SECONDS)
|
||||
@Measurement(time = 2, timeUnit = TimeUnit.SECONDS)
|
||||
public void connectAndDisconnect(SplitGrid connectedGrid) {
|
||||
WiredNodeImpl left = connectedGrid.left, right = connectedGrid.right;
|
||||
|
||||
assertNotEquals(left.getNetwork(), right.getNetwork());
|
||||
left.connectTo(right);
|
||||
assertEquals(left.getNetwork(), right.getNetwork());
|
||||
left.disconnectFrom(right);
|
||||
assertNotEquals(left.getNetwork(), right.getNetwork());
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@Warmup(time = 1, timeUnit = TimeUnit.SECONDS)
|
||||
@Measurement(time = 2, timeUnit = TimeUnit.SECONDS)
|
||||
public void connectAndRemove(SplitGrid connectedGrid) {
|
||||
WiredNodeImpl left = connectedGrid.left, right = connectedGrid.right, centre = connectedGrid.centre;
|
||||
|
||||
assertNotEquals(left.getNetwork(), right.getNetwork());
|
||||
centre.connectTo(left);
|
||||
centre.connectTo(right);
|
||||
assertEquals(left.getNetwork(), right.getNetwork());
|
||||
centre.remove();
|
||||
assertNotEquals(left.getNetwork(), right.getNetwork());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a grid where all nodes are connected to their neighbours.
|
||||
*/
|
||||
@State(Scope.Thread)
|
||||
public static class ConnectedGrid {
|
||||
Grid<WiredNodeImpl> grid;
|
||||
|
||||
@Setup(Level.Invocation)
|
||||
public void setup() {
|
||||
var grid = this.grid = new Grid<>(BRUTE_SIZE);
|
||||
grid.map((existing, pos) -> new NetworkElement("n_" + pos, pos.getX() == pos.getY() && pos.getY() == pos.getZ()).getNode());
|
||||
|
||||
// Connect every node
|
||||
grid.forEach((node, pos) -> {
|
||||
for (var facing : DirectionUtil.FACINGS) {
|
||||
var other = grid.get(pos.relative(facing));
|
||||
if (other != null) node.connectTo(other);
|
||||
}
|
||||
});
|
||||
|
||||
var networks = countNetworks(grid);
|
||||
if (networks.size() != 1) throw new AssertionError("Expected exactly one network.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a grid where the nodes at {@code x < BRUTE_SIZE/2} and {@code x >= BRUTE_SIZE/2} are in separate networks,
|
||||
* but otherwise connected to their neighbours.
|
||||
*/
|
||||
@State(Scope.Thread)
|
||||
public static class SplitGrid {
|
||||
Grid<WiredNodeImpl> grid;
|
||||
WiredNodeImpl left, right, centre;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
var grid = this.grid = new Grid<>(BRUTE_SIZE);
|
||||
grid.map((existing, pos) -> new NetworkElement("n_" + pos, pos.getX() == pos.getY() && pos.getY() == pos.getZ()).getNode());
|
||||
|
||||
// Connect every node
|
||||
grid.forEach((node, pos) -> {
|
||||
for (var facing : DirectionUtil.FACINGS) {
|
||||
var offset = pos.relative(facing);
|
||||
if (offset.getX() >= BRUTE_SIZE / 2 == pos.getX() >= BRUTE_SIZE / 2) {
|
||||
var other = grid.get(offset);
|
||||
if (other != null) node.connectTo(other);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var networks = countNetworks(grid);
|
||||
if (networks.size() != 2) throw new AssertionError("Expected exactly two networks.");
|
||||
for (var network : networks.object2IntEntrySet()) {
|
||||
if (network.getIntValue() != BRUTE_SIZE * BRUTE_SIZE * (BRUTE_SIZE / 2)) {
|
||||
throw new AssertionError("Network is the wrong size");
|
||||
}
|
||||
}
|
||||
|
||||
left = Objects.requireNonNull(grid.get(new BlockPos(BRUTE_SIZE / 2 - 1, 0, 0)));
|
||||
right = Objects.requireNonNull(grid.get(new BlockPos(BRUTE_SIZE / 2, 0, 0)));
|
||||
centre = new NetworkElement("c", false).getNode();
|
||||
}
|
||||
}
|
||||
|
||||
private static Object2IntMap<WiredNetwork> countNetworks(Grid<WiredNodeImpl> grid) {
|
||||
Object2IntMap<WiredNetwork> networks = new Object2IntOpenHashMap<>();
|
||||
grid.forEach((node, pos) -> networks.put(node.network, networks.getOrDefault(node.network, 0) + 1));
|
||||
return networks;
|
||||
}
|
||||
|
||||
private static class Grid<T> {
|
||||
private final int size;
|
||||
private final T[] box;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Grid(int size) {
|
||||
this.size = size;
|
||||
this.box = (T[]) new Object[size * size * size];
|
||||
}
|
||||
|
||||
public T get(BlockPos pos) {
|
||||
int x = pos.getX(), y = pos.getY(), z = pos.getZ();
|
||||
|
||||
return x >= 0 && x < size && y >= 0 && y < size && z >= 0 && z < size
|
||||
? box[x * size * size + y * size + z]
|
||||
: null;
|
||||
}
|
||||
|
||||
public void forEach(BiConsumer<T, BlockPos> transform) {
|
||||
for (var x = 0; x < size; x++) {
|
||||
for (var y = 0; y < size; y++) {
|
||||
for (var z = 0; z < size; z++) {
|
||||
transform.accept(box[x * size * size + y * size + z], new BlockPos(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void map(BiFunction<T, BlockPos, T> transform) {
|
||||
for (var x = 0; x < size; x++) {
|
||||
for (var y = 0; y < size; y++) {
|
||||
for (var z = 0; z < size; z++) {
|
||||
box[x * size * size + y * size + z] = transform.apply(box[x * size * size + y * size + z], new BlockPos(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,19 +9,14 @@ import dan200.computercraft.api.network.wired.WiredNetwork;
|
||||
import dan200.computercraft.api.network.wired.WiredNetworkChange;
|
||||
import dan200.computercraft.api.network.wired.WiredNode;
|
||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||
import dan200.computercraft.shared.util.DirectionUtil;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@ -29,11 +24,11 @@ public class NetworkTest {
|
||||
@Test
|
||||
public void testConnect() {
|
||||
NetworkElement
|
||||
aE = new NetworkElement(null, null, "a"),
|
||||
bE = new NetworkElement(null, null, "b"),
|
||||
cE = new NetworkElement(null, null, "c");
|
||||
aE = new NetworkElement("a"),
|
||||
bE = new NetworkElement("b"),
|
||||
cE = new NetworkElement("c");
|
||||
|
||||
WiredNode
|
||||
WiredNodeImpl
|
||||
aN = aE.getNode(),
|
||||
bN = bE.getNode(),
|
||||
cN = cE.getNode();
|
||||
@ -42,8 +37,8 @@ public class NetworkTest {
|
||||
assertNotEquals(aN.getNetwork(), cN.getNetwork(), "A's and C's network must be different");
|
||||
assertNotEquals(bN.getNetwork(), cN.getNetwork(), "B's and C's network must be different");
|
||||
|
||||
assertTrue(aN.getNetwork().connect(aN, bN), "Must be able to add connection");
|
||||
assertFalse(aN.getNetwork().connect(aN, bN), "Cannot add connection twice");
|
||||
assertTrue(aN.connectTo(bN), "Must be able to add connection");
|
||||
assertFalse(aN.connectTo(bN), "Cannot add connection twice");
|
||||
|
||||
assertEquals(aN.getNetwork(), bN.getNetwork(), "A's and B's network must be equal");
|
||||
assertEquals(Set.of(aN, bN), nodes(aN.getNetwork()), "A's network should be A and B");
|
||||
@ -51,7 +46,7 @@ public class NetworkTest {
|
||||
assertEquals(Set.of("a", "b"), aE.allPeripherals().keySet(), "A's peripheral set should be A, B");
|
||||
assertEquals(Set.of("a", "b"), bE.allPeripherals().keySet(), "B's peripheral set should be A, B");
|
||||
|
||||
aN.getNetwork().connect(aN, cN);
|
||||
aN.connectTo(cN);
|
||||
|
||||
assertEquals(aN.getNetwork(), bN.getNetwork(), "A's and B's network must be equal");
|
||||
assertEquals(aN.getNetwork(), cN.getNetwork(), "A's and C's network must be equal");
|
||||
@ -69,20 +64,20 @@ public class NetworkTest {
|
||||
@Test
|
||||
public void testDisconnectNoChange() {
|
||||
NetworkElement
|
||||
aE = new NetworkElement(null, null, "a"),
|
||||
bE = new NetworkElement(null, null, "b"),
|
||||
cE = new NetworkElement(null, null, "c");
|
||||
aE = new NetworkElement("a"),
|
||||
bE = new NetworkElement("b"),
|
||||
cE = new NetworkElement("c");
|
||||
|
||||
WiredNode
|
||||
WiredNodeImpl
|
||||
aN = aE.getNode(),
|
||||
bN = bE.getNode(),
|
||||
cN = cE.getNode();
|
||||
|
||||
aN.getNetwork().connect(aN, bN);
|
||||
aN.getNetwork().connect(aN, cN);
|
||||
aN.getNetwork().connect(bN, cN);
|
||||
aN.connectTo(bN);
|
||||
aN.connectTo(cN);
|
||||
bN.connectTo(cN);
|
||||
|
||||
aN.getNetwork().disconnect(aN, bN);
|
||||
aN.disconnectFrom(bN);
|
||||
|
||||
assertEquals(aN.getNetwork(), bN.getNetwork(), "A's and B's network must be equal");
|
||||
assertEquals(aN.getNetwork(), cN.getNetwork(), "A's and C's network must be equal");
|
||||
@ -96,19 +91,19 @@ public class NetworkTest {
|
||||
@Test
|
||||
public void testDisconnectLeaf() {
|
||||
NetworkElement
|
||||
aE = new NetworkElement(null, null, "a"),
|
||||
bE = new NetworkElement(null, null, "b"),
|
||||
cE = new NetworkElement(null, null, "c");
|
||||
aE = new NetworkElement("a"),
|
||||
bE = new NetworkElement("b"),
|
||||
cE = new NetworkElement("c");
|
||||
|
||||
WiredNode
|
||||
WiredNodeImpl
|
||||
aN = aE.getNode(),
|
||||
bN = bE.getNode(),
|
||||
cN = cE.getNode();
|
||||
|
||||
aN.getNetwork().connect(aN, bN);
|
||||
aN.getNetwork().connect(aN, cN);
|
||||
aN.connectTo(bN);
|
||||
aN.connectTo(cN);
|
||||
|
||||
aN.getNetwork().disconnect(aN, bN);
|
||||
aN.disconnectFrom(bN);
|
||||
|
||||
assertNotEquals(aN.getNetwork(), bN.getNetwork(), "A's and B's network must not be equal");
|
||||
assertEquals(aN.getNetwork(), cN.getNetwork(), "A's and C's network must be equal");
|
||||
@ -123,23 +118,23 @@ public class NetworkTest {
|
||||
@Test
|
||||
public void testDisconnectSplit() {
|
||||
NetworkElement
|
||||
aE = new NetworkElement(null, null, "a"),
|
||||
aaE = new NetworkElement(null, null, "a_"),
|
||||
bE = new NetworkElement(null, null, "b"),
|
||||
bbE = new NetworkElement(null, null, "b_");
|
||||
aE = new NetworkElement("a"),
|
||||
aaE = new NetworkElement("a_"),
|
||||
bE = new NetworkElement("b"),
|
||||
bbE = new NetworkElement("b_");
|
||||
|
||||
WiredNode
|
||||
WiredNodeImpl
|
||||
aN = aE.getNode(),
|
||||
aaN = aaE.getNode(),
|
||||
bN = bE.getNode(),
|
||||
bbN = bbE.getNode();
|
||||
|
||||
aN.getNetwork().connect(aN, aaN);
|
||||
bN.getNetwork().connect(bN, bbN);
|
||||
aN.connectTo(aaN);
|
||||
bN.connectTo(bbN);
|
||||
|
||||
aN.getNetwork().connect(aN, bN);
|
||||
aN.connectTo(bN);
|
||||
|
||||
aN.getNetwork().disconnect(aN, bN);
|
||||
aN.disconnectFrom(bN);
|
||||
|
||||
assertNotEquals(aN.getNetwork(), bN.getNetwork(), "A's and B's network must not be equal");
|
||||
assertEquals(aN.getNetwork(), aaN.getNetwork(), "A's and A_'s network must be equal");
|
||||
@ -154,7 +149,7 @@ public class NetworkTest {
|
||||
|
||||
@Test
|
||||
public void testRemoveSingle() {
|
||||
var aE = new NetworkElement(null, null, "a");
|
||||
var aE = new NetworkElement("a");
|
||||
var aN = aE.getNode();
|
||||
|
||||
var network = aN.getNetwork();
|
||||
@ -165,20 +160,20 @@ public class NetworkTest {
|
||||
@Test
|
||||
public void testRemoveLeaf() {
|
||||
NetworkElement
|
||||
aE = new NetworkElement(null, null, "a"),
|
||||
bE = new NetworkElement(null, null, "b"),
|
||||
cE = new NetworkElement(null, null, "c");
|
||||
aE = new NetworkElement("a"),
|
||||
bE = new NetworkElement("b"),
|
||||
cE = new NetworkElement("c");
|
||||
|
||||
WiredNode
|
||||
WiredNodeImpl
|
||||
aN = aE.getNode(),
|
||||
bN = bE.getNode(),
|
||||
cN = cE.getNode();
|
||||
|
||||
aN.getNetwork().connect(aN, bN);
|
||||
aN.getNetwork().connect(aN, cN);
|
||||
aN.connectTo(bN);
|
||||
aN.connectTo(cN);
|
||||
|
||||
assertTrue(aN.getNetwork().remove(bN), "Must be able to remove node");
|
||||
assertFalse(aN.getNetwork().remove(bN), "Cannot remove a second time");
|
||||
assertTrue(bN.remove(), "Must be able to remove node");
|
||||
assertFalse(bN.remove(), "Cannot remove a second time");
|
||||
|
||||
assertNotEquals(aN.getNetwork(), bN.getNetwork(), "A's and B's network must not be equal");
|
||||
assertEquals(aN.getNetwork(), cN.getNetwork(), "A's and C's network must be equal");
|
||||
@ -194,26 +189,26 @@ public class NetworkTest {
|
||||
@Test
|
||||
public void testRemoveSplit() {
|
||||
NetworkElement
|
||||
aE = new NetworkElement(null, null, "a"),
|
||||
aaE = new NetworkElement(null, null, "a_"),
|
||||
bE = new NetworkElement(null, null, "b"),
|
||||
bbE = new NetworkElement(null, null, "b_"),
|
||||
cE = new NetworkElement(null, null, "c");
|
||||
aE = new NetworkElement("a"),
|
||||
aaE = new NetworkElement("a_"),
|
||||
bE = new NetworkElement("b"),
|
||||
bbE = new NetworkElement("b_"),
|
||||
cE = new NetworkElement("c");
|
||||
|
||||
WiredNode
|
||||
WiredNodeImpl
|
||||
aN = aE.getNode(),
|
||||
aaN = aaE.getNode(),
|
||||
bN = bE.getNode(),
|
||||
bbN = bbE.getNode(),
|
||||
cN = cE.getNode();
|
||||
|
||||
aN.getNetwork().connect(aN, aaN);
|
||||
bN.getNetwork().connect(bN, bbN);
|
||||
aN.connectTo(aaN);
|
||||
bN.connectTo(bbN);
|
||||
|
||||
cN.getNetwork().connect(aN, cN);
|
||||
cN.getNetwork().connect(bN, cN);
|
||||
cN.connectTo(aN);
|
||||
cN.connectTo(bN);
|
||||
|
||||
cN.getNetwork().remove(cN);
|
||||
cN.remove();
|
||||
|
||||
assertNotEquals(aN.getNetwork(), bN.getNetwork(), "A's and B's network must not be equal");
|
||||
assertEquals(aN.getNetwork(), aaN.getNetwork(), "A's and A_'s network must be equal");
|
||||
@ -228,96 +223,30 @@ public class NetworkTest {
|
||||
assertEquals(Set.of(), cE.allPeripherals().keySet(), "C's peripheral set should be empty");
|
||||
}
|
||||
|
||||
private static final int BRUTE_SIZE = 16;
|
||||
private static final int TOGGLE_CONNECTION_TIMES = 5;
|
||||
private static final int TOGGLE_NODE_TIMES = 5;
|
||||
|
||||
@Test
|
||||
@Disabled("Takes a long time to run, mostly for stress testing")
|
||||
public void testLarge() {
|
||||
var grid = new Grid<WiredNode>(BRUTE_SIZE);
|
||||
grid.map((existing, pos) -> new NetworkElement(null, null, "n_" + pos).getNode());
|
||||
|
||||
// Test connecting
|
||||
{
|
||||
var start = System.nanoTime();
|
||||
|
||||
grid.forEach((existing, pos) -> {
|
||||
for (var facing : DirectionUtil.FACINGS) {
|
||||
var offset = pos.relative(facing);
|
||||
if (offset.getX() > BRUTE_SIZE / 2 == pos.getX() > BRUTE_SIZE / 2) {
|
||||
var other = grid.get(offset);
|
||||
if (other != null) existing.getNetwork().connect(existing, other);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var end = System.nanoTime();
|
||||
|
||||
System.out.printf("Connecting %s³ nodes took %s seconds\n", BRUTE_SIZE, (end - start) * 1e-9);
|
||||
}
|
||||
|
||||
// Test toggling
|
||||
{
|
||||
var left = grid.get(new BlockPos(BRUTE_SIZE / 2, 0, 0));
|
||||
var right = grid.get(new BlockPos(BRUTE_SIZE / 2 + 1, 0, 0));
|
||||
assertNotEquals(left.getNetwork(), right.getNetwork());
|
||||
|
||||
var start = System.nanoTime();
|
||||
for (var i = 0; i < TOGGLE_CONNECTION_TIMES; i++) {
|
||||
left.getNetwork().connect(left, right);
|
||||
left.getNetwork().disconnect(left, right);
|
||||
}
|
||||
|
||||
var end = System.nanoTime();
|
||||
|
||||
System.out.printf("Toggling connection %s times took %s seconds\n", TOGGLE_CONNECTION_TIMES, (end - start) * 1e-9);
|
||||
}
|
||||
|
||||
{
|
||||
var left = grid.get(new BlockPos(BRUTE_SIZE / 2, 0, 0));
|
||||
var right = grid.get(new BlockPos(BRUTE_SIZE / 2 + 1, 0, 0));
|
||||
var centre = new NetworkElement(null, null, "c").getNode();
|
||||
assertNotEquals(left.getNetwork(), right.getNetwork());
|
||||
|
||||
var start = System.nanoTime();
|
||||
for (var i = 0; i < TOGGLE_NODE_TIMES; i++) {
|
||||
left.getNetwork().connect(left, centre);
|
||||
right.getNetwork().connect(right, centre);
|
||||
|
||||
left.getNetwork().remove(centre);
|
||||
}
|
||||
|
||||
var end = System.nanoTime();
|
||||
|
||||
System.out.printf("Toggling node %s times took %s seconds\n", TOGGLE_NODE_TIMES, (end - start) * 1e-9);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class NetworkElement implements WiredElement {
|
||||
private final Level world;
|
||||
private final Vec3 position;
|
||||
static final class NetworkElement implements WiredElement {
|
||||
private final String id;
|
||||
private final WiredNode node;
|
||||
private final WiredNodeImpl node;
|
||||
private final Map<String, IPeripheral> localPeripherals = new HashMap<>();
|
||||
private final Map<String, IPeripheral> remotePeripherals = new HashMap<>();
|
||||
|
||||
private NetworkElement(Level world, Vec3 position, String id) {
|
||||
this.world = world;
|
||||
this.position = position;
|
||||
NetworkElement(String id) {
|
||||
this(id, true);
|
||||
}
|
||||
|
||||
NetworkElement(String id, boolean peripheral) {
|
||||
this.id = id;
|
||||
this.node = new WiredNodeImpl(this);
|
||||
this.addPeripheral(id);
|
||||
if (peripheral) addPeripheral(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Level getLevel() {
|
||||
return world;
|
||||
throw new IllegalStateException("Unexpected call to getLevel()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 getPosition() {
|
||||
return position;
|
||||
throw new IllegalStateException("Unexpected call to getPosition()");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -331,7 +260,7 @@ public class NetworkTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public WiredNode getNode() {
|
||||
public WiredNodeImpl getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -364,45 +293,6 @@ public class NetworkTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static class Grid<T> {
|
||||
private final int size;
|
||||
private final T[] box;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Grid(int size) {
|
||||
this.size = size;
|
||||
this.box = (T[]) new Object[size * size * size];
|
||||
}
|
||||
|
||||
public T get(BlockPos pos) {
|
||||
int x = pos.getX(), y = pos.getY(), z = pos.getZ();
|
||||
|
||||
return x >= 0 && x < size && y >= 0 && y < size && z >= 0 && z < size
|
||||
? box[x * size * size + y * size + z]
|
||||
: null;
|
||||
}
|
||||
|
||||
public void forEach(BiConsumer<T, BlockPos> transform) {
|
||||
for (var x = 0; x < size; x++) {
|
||||
for (var y = 0; y < size; y++) {
|
||||
for (var z = 0; z < size; z++) {
|
||||
transform.accept(box[x * size * size + y * size + z], new BlockPos(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void map(BiFunction<T, BlockPos, T> transform) {
|
||||
for (var x = 0; x < size; x++) {
|
||||
for (var y = 0; y < size; y++) {
|
||||
for (var z = 0; z < size; z++) {
|
||||
box[x * size * size + y * size + z] = transform.apply(box[x * size * size + y * size + z], new BlockPos(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<WiredNodeImpl> nodes(WiredNetwork network) {
|
||||
return ((WiredNetworkImpl) network).nodes;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user