diff --git a/README.md b/README.md index 2b8af67..ac2d141 100644 --- a/README.md +++ b/README.md @@ -1 +1,36 @@ -Check the [example](https://github.com/nothub/TinyPubSub/blob/master/src/test/java/cc/neckbeard/tinypubsub/example/Example.java) for a usage snippet. +A tiny and fast pubsub implementation with priorities and canceling. + +Check the +[example](https://github.com/nothub/TinyEventBus/blob/master/src/test/java/cc/neckbeard/tinypubsub/example/Example.java) +for a usage snippet. + +--- + +[benchmarks](https://github.com/nothub/TinyEventBus/tree/master/src/test/java/cc/neckbeard/tinypubsub/benchmark) ( +openjdk 8, xeon e3-1230 3.30ghz): + +``` +pub +subs: 1_000 +pubs: 1_000 +47,681,726ns (47ms) +``` + +``` +pub +subs: 100 +pubs: 100_000 +58,357,624ns (58ms) +``` + +``` +reg +subs: 1_000 +2,740,465ns (2ms) +``` + +``` +del +subs: 1_000 +7,297,579ns (7ms) +``` diff --git a/pom.xml b/pom.xml index 9a7662f..8e57350 100644 --- a/pom.xml +++ b/pom.xml @@ -5,10 +5,10 @@ 4.0.0 cc.neckbeard - TinyPubSub - 0.3.1 + TinyEventBus + 0.4.0 - ${project.artifactId} + ${project.groupId}:${project.artifactId} jar diff --git a/src/main/java/cc/neckbeard/tinypubsub/Bus.java b/src/main/java/cc/neckbeard/tinyeventbus/Bus.java similarity index 96% rename from src/main/java/cc/neckbeard/tinypubsub/Bus.java rename to src/main/java/cc/neckbeard/tinyeventbus/Bus.java index a09c918..025948f 100644 --- a/src/main/java/cc/neckbeard/tinypubsub/Bus.java +++ b/src/main/java/cc/neckbeard/tinyeventbus/Bus.java @@ -1,4 +1,4 @@ -package cc.neckbeard.tinypubsub; +package cc.neckbeard.tinyeventbus; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; diff --git a/src/main/java/cc/neckbeard/tinypubsub/Cancellable.java b/src/main/java/cc/neckbeard/tinyeventbus/Cancellable.java similarity index 64% rename from src/main/java/cc/neckbeard/tinypubsub/Cancellable.java rename to src/main/java/cc/neckbeard/tinyeventbus/Cancellable.java index 56abf7f..289d360 100644 --- a/src/main/java/cc/neckbeard/tinypubsub/Cancellable.java +++ b/src/main/java/cc/neckbeard/tinyeventbus/Cancellable.java @@ -1,4 +1,4 @@ -package cc.neckbeard.tinypubsub; +package cc.neckbeard.tinyeventbus; public interface Cancellable { diff --git a/src/main/java/cc/neckbeard/tinypubsub/Sub.java b/src/main/java/cc/neckbeard/tinyeventbus/Sub.java similarity index 65% rename from src/main/java/cc/neckbeard/tinypubsub/Sub.java rename to src/main/java/cc/neckbeard/tinyeventbus/Sub.java index df38141..79c1fdb 100644 --- a/src/main/java/cc/neckbeard/tinypubsub/Sub.java +++ b/src/main/java/cc/neckbeard/tinyeventbus/Sub.java @@ -1,4 +1,4 @@ -package cc.neckbeard.tinypubsub; +package cc.neckbeard.tinyeventbus; import net.jodah.typetools.TypeResolver; import org.jetbrains.annotations.NotNull; @@ -11,12 +11,32 @@ public class Sub implements Comparable> { public final Class type; public final Consumer consumer; - public Sub(int prio, Consumer consumer) { + public Sub(Consumer consumer, int prio) { this.prio = prio; this.type = TypeResolver.resolveRawArguments(Consumer.class, consumer.getClass())[0]; this.consumer = consumer; } + public Sub(int prio, Consumer consumer) { + this(consumer, 0); + } + + public Sub(Consumer consumer) { + this(consumer, 0); + } + + public static Sub of(Consumer consumer, int prio) { + return new Sub<>(consumer, prio); + } + + public static Sub of(int prio, Consumer consumer) { + return new Sub<>(consumer, prio); + } + + public static Sub of(Consumer consumer) { + return new Sub<>(consumer); + } + public void accept(Object o) { //noinspection unchecked consumer.accept((T) o); diff --git a/src/test/java/cc/neckbeard/tinyeventbus/benchmark/DelBenchmark.java b/src/test/java/cc/neckbeard/tinyeventbus/benchmark/DelBenchmark.java new file mode 100644 index 0000000..ce3ce52 --- /dev/null +++ b/src/test/java/cc/neckbeard/tinyeventbus/benchmark/DelBenchmark.java @@ -0,0 +1,46 @@ +package cc.neckbeard.tinyeventbus.benchmark; + +import cc.neckbeard.tinyeventbus.Bus; +import cc.neckbeard.tinyeventbus.Sub; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.IntStream; + +@Execution(ExecutionMode.SAME_THREAD) +public class DelBenchmark { + + private static final Bus bus = new Bus(); + + @Test + void benchmark() { + + System.out.println("del"); + + final int subs = 1_000; + System.out.println("subs: " + subs); + + List> listenerContainers = new ArrayList<>(); + + IntStream.range(0, subs).forEach(i -> listenerContainers.add(new Sub<>(0, s -> {}))); + + IntStream + .range(0, subs) + .forEach(i -> bus.reg(listenerContainers.get(i))); + + final long start = System.nanoTime(); + + IntStream + .range(0, subs) + .forEach(i -> bus.del(listenerContainers.get(i))); + + final long end = System.nanoTime() - start; + + System.out.printf("%,dns (%,dms)\n", end, end / 1000000); + + } + +} diff --git a/src/test/java/cc/neckbeard/tinypubsub/tests/PubSubTest.java b/src/test/java/cc/neckbeard/tinyeventbus/benchmark/PubBenchmark.java similarity index 73% rename from src/test/java/cc/neckbeard/tinypubsub/tests/PubSubTest.java rename to src/test/java/cc/neckbeard/tinyeventbus/benchmark/PubBenchmark.java index 7464bce..38694c2 100644 --- a/src/test/java/cc/neckbeard/tinypubsub/tests/PubSubTest.java +++ b/src/test/java/cc/neckbeard/tinyeventbus/benchmark/PubBenchmark.java @@ -1,7 +1,8 @@ -package cc.neckbeard.tinypubsub.tests; +package cc.neckbeard.tinyeventbus.benchmark; -import cc.neckbeard.tinypubsub.Bus; -import cc.neckbeard.tinypubsub.Sub; +import cc.neckbeard.tinyeventbus.Bus; +import cc.neckbeard.tinyeventbus.Sub; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; @@ -9,17 +10,19 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.IntStream; + @Execution(ExecutionMode.SAME_THREAD) -public class PubSubTest { +public class PubBenchmark { private static final String event = ""; + private static final Bus bus = new Bus(); private static int hits = 0; @Test - void run() { + void benchmark() { - System.out.println("com.github.nothub TinyPubSub 8c9f424f85"); + System.out.println("pub"); final int subs = 1_000; final int pubs = 1_000; @@ -30,20 +33,21 @@ void run() { IntStream.range(0, subs).forEach(i -> listenerContainers.add(new Sub<>(0, s -> hits++))); - final long start = System.nanoTime(); - IntStream .range(0, subs) .forEach(i -> bus.reg(listenerContainers.get(i))); + final long start = System.nanoTime(); + IntStream .range(0, pubs) .forEach(i -> bus.pub(event)); final long end = System.nanoTime() - start; - System.out.println("hits: " + hits); - System.out.printf("%,dns (%,dms)", end, end / 1000000); + System.out.printf("%,dns (%,dms)\n", end, end / 1000000); + + Assertions.assertEquals(subs * pubs, hits); } diff --git a/src/test/java/cc/neckbeard/tinyeventbus/benchmark/RegBenchmark.java b/src/test/java/cc/neckbeard/tinyeventbus/benchmark/RegBenchmark.java new file mode 100644 index 0000000..bb9b922 --- /dev/null +++ b/src/test/java/cc/neckbeard/tinyeventbus/benchmark/RegBenchmark.java @@ -0,0 +1,42 @@ +package cc.neckbeard.tinyeventbus.benchmark; + +import cc.neckbeard.tinyeventbus.Bus; +import cc.neckbeard.tinyeventbus.Sub; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.IntStream; + +@Execution(ExecutionMode.SAME_THREAD) +public class RegBenchmark { + + private static final Bus bus = new Bus(); + + @Test + void benchmark() { + + System.out.println("reg"); + + final int subs = 1_000; + System.out.println("subs: " + subs); + + List> listenerContainers = new ArrayList<>(); + + IntStream.range(0, subs).forEach(i -> listenerContainers.add(new Sub<>(0, s -> {}))); + + final long start = System.nanoTime(); + + IntStream + .range(0, subs) + .forEach(i -> bus.reg(listenerContainers.get(i))); + + final long end = System.nanoTime() - start; + + System.out.printf("%,dns (%,dms)\n", end, end / 1000000); + + } + +} diff --git a/src/test/java/cc/neckbeard/tinypubsub/example/Example.java b/src/test/java/cc/neckbeard/tinyeventbus/example/Example.java similarity index 79% rename from src/test/java/cc/neckbeard/tinypubsub/example/Example.java rename to src/test/java/cc/neckbeard/tinyeventbus/example/Example.java index 4753f07..806c697 100644 --- a/src/test/java/cc/neckbeard/tinypubsub/example/Example.java +++ b/src/test/java/cc/neckbeard/tinyeventbus/example/Example.java @@ -1,14 +1,14 @@ -package cc.neckbeard.tinypubsub.example; +package cc.neckbeard.tinyeventbus.example; -import cc.neckbeard.tinypubsub.Bus; -import cc.neckbeard.tinypubsub.Cancellable; -import cc.neckbeard.tinypubsub.Sub; +import cc.neckbeard.tinyeventbus.Bus; +import cc.neckbeard.tinyeventbus.Cancellable; +import cc.neckbeard.tinyeventbus.Sub; public class Example { private static String msg = ""; - Sub first = new Sub<>(0, e -> msg = e.str); + Sub first = new Sub<>( e -> msg = e.str); Sub second = new Sub<>(1, e -> { if (e.str.equals("foobar")) e.cancelled = true; diff --git a/src/test/java/cc/neckbeard/tinypubsub/tests/BooleanEvent.java b/src/test/java/cc/neckbeard/tinyeventbus/tests/BooleanEvent.java similarity index 74% rename from src/test/java/cc/neckbeard/tinypubsub/tests/BooleanEvent.java rename to src/test/java/cc/neckbeard/tinyeventbus/tests/BooleanEvent.java index 95befcd..838d5b0 100644 --- a/src/test/java/cc/neckbeard/tinypubsub/tests/BooleanEvent.java +++ b/src/test/java/cc/neckbeard/tinyeventbus/tests/BooleanEvent.java @@ -1,4 +1,4 @@ -package cc.neckbeard.tinypubsub.tests; +package cc.neckbeard.tinyeventbus.tests; class BooleanEvent { diff --git a/src/test/java/cc/neckbeard/tinypubsub/tests/InstanceTests.java b/src/test/java/cc/neckbeard/tinyeventbus/tests/InstanceTests.java similarity index 81% rename from src/test/java/cc/neckbeard/tinypubsub/tests/InstanceTests.java rename to src/test/java/cc/neckbeard/tinyeventbus/tests/InstanceTests.java index 7db3df4..acd81be 100644 --- a/src/test/java/cc/neckbeard/tinypubsub/tests/InstanceTests.java +++ b/src/test/java/cc/neckbeard/tinyeventbus/tests/InstanceTests.java @@ -1,7 +1,7 @@ -package cc.neckbeard.tinypubsub.tests; +package cc.neckbeard.tinyeventbus.tests; -import cc.neckbeard.tinypubsub.Bus; -import cc.neckbeard.tinypubsub.Sub; +import cc.neckbeard.tinyeventbus.Bus; +import cc.neckbeard.tinyeventbus.Sub; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; @@ -15,7 +15,7 @@ class InstanceTests { private static Bus bus; private static boolean invoked; - Sub sub = new Sub<>(0, e -> invoked = e.value); + Sub sub = Sub.of(e -> invoked = e.value); @BeforeAll static void setUp() { diff --git a/src/test/java/cc/neckbeard/tinypubsub/tests/MultiTest.java b/src/test/java/cc/neckbeard/tinyeventbus/tests/MultiTest.java similarity index 72% rename from src/test/java/cc/neckbeard/tinypubsub/tests/MultiTest.java rename to src/test/java/cc/neckbeard/tinyeventbus/tests/MultiTest.java index 55c3bb2..c5bf233 100644 --- a/src/test/java/cc/neckbeard/tinypubsub/tests/MultiTest.java +++ b/src/test/java/cc/neckbeard/tinyeventbus/tests/MultiTest.java @@ -1,7 +1,7 @@ -package cc.neckbeard.tinypubsub.tests; +package cc.neckbeard.tinyeventbus.tests; -import cc.neckbeard.tinypubsub.Bus; -import cc.neckbeard.tinypubsub.Sub; +import cc.neckbeard.tinyeventbus.Bus; +import cc.neckbeard.tinyeventbus.Sub; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -14,9 +14,9 @@ class MultiTest { private static Bus bus = new Bus(); private static int hits; - private final Sub sub = new Sub<>(0, o -> hits++); + private final Sub sub = new Sub<>(o -> hits++); - private static final Sub subStatic = new Sub<>(0, o -> hits++); + private static final Sub subStatic = Sub.of(o -> hits++); @BeforeEach void setUp() { @@ -42,8 +42,8 @@ void regStatic() { @Test void regInline() { - bus.reg(new Sub<>(0, o -> hits++)); - bus.reg(new Sub<>(0, o -> hits++)); + bus.reg(new Sub<>(o -> hits++)); + bus.reg(Sub.of(o -> hits++)); bus.pub(new Object()); Assertions.assertEquals(2, hits); } diff --git a/src/test/java/cc/neckbeard/tinypubsub/tests/OrderTests.java b/src/test/java/cc/neckbeard/tinyeventbus/tests/OrderTests.java similarity index 55% rename from src/test/java/cc/neckbeard/tinypubsub/tests/OrderTests.java rename to src/test/java/cc/neckbeard/tinyeventbus/tests/OrderTests.java index 1073f26..b4a3162 100644 --- a/src/test/java/cc/neckbeard/tinypubsub/tests/OrderTests.java +++ b/src/test/java/cc/neckbeard/tinyeventbus/tests/OrderTests.java @@ -1,7 +1,7 @@ -package cc.neckbeard.tinypubsub.tests; +package cc.neckbeard.tinyeventbus.tests; -import cc.neckbeard.tinypubsub.Bus; -import cc.neckbeard.tinypubsub.Sub; +import cc.neckbeard.tinyeventbus.Bus; +import cc.neckbeard.tinyeventbus.Sub; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -11,19 +11,19 @@ class OrderTests { private static Bus bus; private static String str; + Sub subC1 = new Sub<>(e -> str += "C"); + Sub subC2 = Sub.of(e -> str += "C"); + Sub subE = new Sub<>(e -> str += "E", -2); + Sub subA = Sub.of(e -> str += "A", 2); + Sub subB = Sub.of(e -> str += "B", 1); + Sub subD = new Sub<>(e -> str += "D", -1); + @BeforeAll static void setUp() { bus = new Bus(); str = ""; } - Sub subC1 = new Sub<>(0, e -> str += "C"); - Sub subC2 = new Sub<>(0, e -> str += "C"); - Sub subE = new Sub<>(-2, e -> str += "E"); - Sub subA = new Sub<>(2, e -> str += "A"); - Sub subB = new Sub<>(1, e -> str += "B"); - Sub subD = new Sub<>(-1, e -> str += "D"); - @Test void order() { bus.reg(subC1); diff --git a/src/test/java/cc/neckbeard/tinypubsub/tests/StaticTests.java b/src/test/java/cc/neckbeard/tinyeventbus/tests/StaticTests.java similarity index 81% rename from src/test/java/cc/neckbeard/tinypubsub/tests/StaticTests.java rename to src/test/java/cc/neckbeard/tinyeventbus/tests/StaticTests.java index f0a9930..64c6b7c 100644 --- a/src/test/java/cc/neckbeard/tinypubsub/tests/StaticTests.java +++ b/src/test/java/cc/neckbeard/tinyeventbus/tests/StaticTests.java @@ -1,7 +1,7 @@ -package cc.neckbeard.tinypubsub.tests; +package cc.neckbeard.tinyeventbus.tests; -import cc.neckbeard.tinypubsub.Bus; -import cc.neckbeard.tinypubsub.Sub; +import cc.neckbeard.tinyeventbus.Bus; +import cc.neckbeard.tinyeventbus.Sub; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Order; @@ -15,7 +15,7 @@ class StaticTests { private static Bus bus; private static boolean invoked; - Sub sub = new Sub<>(0, e -> invoked = e.value); + Sub sub = new Sub<>(e -> invoked = e.value, 0); @BeforeAll static void setUp() { diff --git a/src/test/java/cc/neckbeard/tinypubsub/tests/StressTests.java b/src/test/java/cc/neckbeard/tinyeventbus/tests/StressTests.java similarity index 82% rename from src/test/java/cc/neckbeard/tinypubsub/tests/StressTests.java rename to src/test/java/cc/neckbeard/tinyeventbus/tests/StressTests.java index e604cc8..8db277e 100644 --- a/src/test/java/cc/neckbeard/tinypubsub/tests/StressTests.java +++ b/src/test/java/cc/neckbeard/tinyeventbus/tests/StressTests.java @@ -1,7 +1,7 @@ -package cc.neckbeard.tinypubsub.tests; +package cc.neckbeard.tinyeventbus.tests; -import cc.neckbeard.tinypubsub.Bus; -import cc.neckbeard.tinypubsub.Sub; +import cc.neckbeard.tinyeventbus.Bus; +import cc.neckbeard.tinyeventbus.Sub; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -23,11 +23,11 @@ void setUp() { hits = 0; } - Sub subA = new Sub<>(Integer.MAX_VALUE, o -> hits++); - Sub subB = new Sub<>(42, o -> hits++); - Sub subC = new Sub<>(0, o -> hits++); - Sub subD = new Sub<>(-42, o -> hits++); - Sub subE = new Sub<>(Integer.MIN_VALUE, o -> hits++); + Sub subA = Sub.of( o -> hits++, Integer.MAX_VALUE); + Sub subB = new Sub<>(o -> hits++, 42); + Sub subC = Sub.of(o -> hits++); + Sub subD = new Sub<>(o -> hits++, -42); + Sub subE = Sub.of( o -> hits++, Integer.MIN_VALUE); @Test @DisplayName("pub 2m") diff --git a/src/test/java/cc/neckbeard/tinypubsub/tests/UniqueTest.java b/src/test/java/cc/neckbeard/tinyeventbus/tests/UniqueTest.java similarity index 54% rename from src/test/java/cc/neckbeard/tinypubsub/tests/UniqueTest.java rename to src/test/java/cc/neckbeard/tinyeventbus/tests/UniqueTest.java index 6404478..5a48ad1 100644 --- a/src/test/java/cc/neckbeard/tinypubsub/tests/UniqueTest.java +++ b/src/test/java/cc/neckbeard/tinyeventbus/tests/UniqueTest.java @@ -1,7 +1,7 @@ -package cc.neckbeard.tinypubsub.tests; +package cc.neckbeard.tinyeventbus.tests; -import cc.neckbeard.tinypubsub.Bus; -import cc.neckbeard.tinypubsub.Sub; +import cc.neckbeard.tinyeventbus.Bus; +import cc.neckbeard.tinyeventbus.Sub; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -20,14 +20,24 @@ void setUp() { hits = 0; } - Sub sub = new Sub<>(0, o -> hits++); + Sub sub = new Sub<>( o -> hits++); @Test - void multireg() { + void multireg_a() { bus.reg(sub); bus.reg(sub); bus.pub(new Object()); Assertions.assertEquals(1, hits); } + @Test + void multireg_b() { + bus.reg(new Sub<>( o -> hits++)); + bus.reg(new Sub<>( o -> hits++)); + bus.reg(Sub.of( o -> hits++)); + bus.reg(Sub.of( o -> hits++)); + bus.pub(new Object()); + Assertions.assertEquals(4, hits); + } + }