diff --git a/broker/pom.xml b/broker/pom.xml
index b7b128c9..94f6a604 100644
--- a/broker/pom.xml
+++ b/broker/pom.xml
@@ -171,6 +171,13 @@
${project.build.outputDirectory}/META-INF/MANIFEST.MF
+
+
+
+ test-jar
+
+
+
org.apache.felix
diff --git a/perf/pom.xml b/perf/pom.xml
index cba2ff22..d1da0cb3 100644
--- a/perf/pom.xml
+++ b/perf/pom.xml
@@ -25,6 +25,19 @@
${project.version}
+
+ ${project.groupId}
+ moquette-broker
+ ${project.version}
+
+
+
+ ${project.groupId}
+ moquette-broker
+ ${project.version}
+ test-jar
+
+
diff --git a/perf/src/main/java/io/moquette/spi/impl/subscriptions/PerformanceTest.java b/perf/src/main/java/io/moquette/spi/impl/subscriptions/PerformanceTest.java
new file mode 100644
index 00000000..d4b1e306
--- /dev/null
+++ b/perf/src/main/java/io/moquette/spi/impl/subscriptions/PerformanceTest.java
@@ -0,0 +1,84 @@
+
+package io.moquette.spi.impl.subscriptions;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadMXBean;
+import io.moquette.parser.proto.messages.AbstractMessage;
+import io.moquette.spi.ISessionsStore;
+import io.moquette.spi.impl.MemoryStorageService;
+
+public class PerformanceTest {
+
+ // Set CPU governor and max frequency to lowest value for this test
+ /* debian:
+ cpufreq-set -g performance -u 800MHz -c 0
+ cpufreq-set -g performance -u 800MHz -c 1
+ cpufreq-set -g performance -u 800MHz -c 2
+ cpufreq-set -g performance -u 800MHz -c 3
+ */
+ public static void main(String[] args) throws IOException, InterruptedException {
+ SubscriptionsStore store = new SubscriptionsStore();
+ MemoryStorageService memStore = new MemoryStorageService();
+ memStore.initStore();
+ ISessionsStore aSessionsStore = memStore.sessionsStore();
+ store.init(aSessionsStore);
+
+ int times = 10000;
+
+ int users = 500;
+ int devices = 5;
+ int values = 3;
+ int subs = 2;
+ int n = users * devices * values * subs;
+
+ ThreadMXBean b = ManagementFactory.getThreadMXBean();
+
+ String[] topics = new String[n];
+ for (int i = 0; i < n; i++) {
+ topics[i] = (i % users) + "/" + ((i / users) % devices) + "/" + ((i / (users * devices)) % values) + "/"
+ + ((i / (users * devices * values)) % subs);
+
+ Subscription sub = new Subscription("CLI_ID_" + (i % users), topics[i], AbstractMessage.QOSType.MOST_ONE);
+ aSessionsStore.addNewSubscription(sub);
+ store.add(sub.asClientTopicCouple());
+ }
+
+ long min = Long.MAX_VALUE;
+ //AtomicLong min = new AtomicLong(Long.MAX_VALUE);
+
+ System.out.println("Store size: " + store.size() + " " + n);
+
+ // warm up
+ for (int i = 0; i < n; i++) {
+ store.matches(topics[i]);
+ }
+
+ System.out.println("press return for start");
+ System.in.read();
+
+// IntStream.range(0, times)
+// .parallel()
+// .forEach(j -> {
+
+ for (int j = 0; j < times; j++) {
+
+ System.gc();
+ Thread.yield();
+
+ long time = b.getCurrentThreadCpuTime();
+ for (int i = 0; i < n; i++) {
+ store.matches(topics[i]);
+ }
+ long time2 = b.getCurrentThreadCpuTime() - time;
+ min = Math.min(min, time2);
+// min.updateAndGet(c -> Math.min(c, time2));
+ System.out.println(".." + j + ": " + time2 + " min:" + min);
+
+ }
+// });
+
+ System.out.println("min:" + min);
+
+ }
+}