You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@artemis.apache.org by cl...@apache.org on 2026/04/29 18:21:42 UTC
(artemis-native) 01/03: Adding JMH performance test
This is an automated email from the ASF dual-hosted git repository.
clebertsuconic pushed a commit to branch branch-jni
in repository https://gitbox.apache.org/repos/asf/artemis-native.git
commit 43403880a7df61d7d12666aa4f18a1cb0cebbff7
Author: mayankkunwar <ms...@gmail.com>
AuthorDate: Fri Apr 24 17:07:38 2026 +0100
Adding JMH performance test
---
pom.xml | 27 ++++
.../test/performance/jmh/BenchmarkRunner.java | 11 ++
.../test/performance/jmh/LibaioBenchmark.java | 165 +++++++++++++++++++++
3 files changed, 203 insertions(+)
diff --git a/pom.xml b/pom.xml
index d4693f8..107367f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,6 +38,7 @@
<version.org.jacoco.plugin>0.8.6</version.org.jacoco.plugin>
<surefire.version>2.22.2</surefire.version>
<junit.version>4.13.2</junit.version>
+ <jmh.version>1.37</jmh.version>
<maven.bundle.plugin.version>5.1.2</maven.bundle.plugin.version>
<exec-maven-plugin.version>3.0.0</exec-maven-plugin.version>
<maven-enforcer-plugin.version>3.0.0</maven-enforcer-plugin.version>
@@ -98,6 +99,18 @@
<scope>test</scope>
<!-- License: EPL 1.0 -->
</dependency>
+ <dependency>
+ <groupId>org.openjdk.jmh</groupId>
+ <artifactId>jmh-core</artifactId>
+ <version>${jmh.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.openjdk.jmh</groupId>
+ <artifactId>jmh-generator-annprocess</artifactId>
+ <version>${jmh.version}</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.ant</artifactId>
@@ -261,6 +274,20 @@
<build>
<pluginManagement>
<plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.11.0</version>
+ <configuration>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>org.openjdk.jmh</groupId>
+ <artifactId>jmh-generator-annprocess</artifactId>
+ <version>${jmh.version}</version>
+ </path>
+ </annotationProcessorPaths>
+ </configuration>
+ </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
diff --git a/src/test/java/org/apache/activemq/artemis/nativo/jlibaio/test/performance/jmh/BenchmarkRunner.java b/src/test/java/org/apache/activemq/artemis/nativo/jlibaio/test/performance/jmh/BenchmarkRunner.java
new file mode 100644
index 0000000..ca57d78
--- /dev/null
+++ b/src/test/java/org/apache/activemq/artemis/nativo/jlibaio/test/performance/jmh/BenchmarkRunner.java
@@ -0,0 +1,11 @@
+package org.apache.activemq.artemis.nativo.jlibaio.test.performance.jmh;
+
+import org.openjdk.jmh.Main;
+
+import java.io.IOException;
+
+public class BenchmarkRunner {
+ public static void main(String[] args) throws IOException {
+ Main.main(args);
+ }
+}
diff --git a/src/test/java/org/apache/activemq/artemis/nativo/jlibaio/test/performance/jmh/LibaioBenchmark.java b/src/test/java/org/apache/activemq/artemis/nativo/jlibaio/test/performance/jmh/LibaioBenchmark.java
new file mode 100644
index 0000000..44310df
--- /dev/null
+++ b/src/test/java/org/apache/activemq/artemis/nativo/jlibaio/test/performance/jmh/LibaioBenchmark.java
@@ -0,0 +1,165 @@
+package org.apache.activemq.artemis.nativo.jlibaio.test.performance.jmh;
+
+import org.apache.activemq.artemis.nativo.jlibaio.LibaioContext;
+import org.apache.activemq.artemis.nativo.jlibaio.LibaioFile;
+import org.apache.activemq.artemis.nativo.jlibaio.SubmitInfo;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+
+import java.io.File;
+import java.nio.ByteBuffer;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@Fork(value = 2)
+@Warmup(iterations = 5, time = 200, timeUnit = TimeUnit.MILLISECONDS)
+@Measurement(iterations = 10, time = 200, timeUnit = TimeUnit.MILLISECONDS)
+public class LibaioBenchmark {
+ private static final int FILE_SIZE = 10000 * 4096;
+ private static final int BLOCK_SIZE = 4096;
+
+ @Param({"2048"})
+ private static int LIBAIO_QUEUE_SIZE;
+
+ @Param({"10000"})
+ private int recordCount;
+
+ private File file;
+ private LibaioContext<SubmitInfo> control;
+ private LibaioFile<SubmitInfo> libaioFile;
+
+ private ByteBuffer headerBuffer;
+ private ByteBuffer recordBuffer;
+
+ private final AtomicReference<CountDownLatch> currentLatch = new AtomicReference<>();
+
+ private Thread pollThread;
+ private volatile boolean polling = true;
+
+ private final SubmitInfo callback = new SubmitInfo() {
+ @Override
+ public void onError(int errno, String message) {
+ // ignore for benchmark
+ }
+
+ @Override
+ public void done() {
+ CountDownLatch latch = currentLatch.get();
+ if (latch != null) {
+ latch.countDown();
+ }
+ }
+ };
+
+ private long fileId = 1L;
+
+ @Setup(Level.Trial)
+ public void setup() throws Exception {
+ file = File.createTempFile("aio-bench-jni-", ".dat");
+
+ control = new LibaioContext<>(LIBAIO_QUEUE_SIZE, true, true);
+ libaioFile = control.openFile(file, true);
+
+ libaioFile.fallocate(FILE_SIZE);
+
+ headerBuffer = LibaioContext.newAlignedBuffer(BLOCK_SIZE, BLOCK_SIZE);
+ recordBuffer = LibaioContext.newAlignedBuffer(BLOCK_SIZE, BLOCK_SIZE);
+
+ initRecord(headerBuffer); // filling the record clock with 1
+ initRecord(recordBuffer); // filling the record clock with 1
+
+ fillHeader(fileId);
+ updateRecord(recordBuffer, fileId, 0L);
+
+ polling = true;
+ pollThread = new Thread(() -> {
+ try {
+ while (polling && !Thread.currentThread().isInterrupted()) {
+ control.poll();
+ }
+ } catch (Throwable t) {
+ }
+ }, "aio-jmh-jni-poll-thread");
+ pollThread.setDaemon(true);
+ pollThread.start();
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ polling = false;
+
+ if (pollThread != null) {
+ pollThread.interrupt();
+ pollThread.join(TimeUnit.SECONDS.toMillis(10));
+ }
+
+ if (libaioFile != null) {
+ libaioFile.close();
+ }
+ if (control != null) {
+ control.close();
+ }
+ if (headerBuffer != null) {
+ LibaioContext.freeBuffer(headerBuffer);
+ }
+ if (recordBuffer != null) {
+ LibaioContext.freeBuffer(recordBuffer);
+ }
+ if (file != null) {
+ file.delete();
+ }
+ }
+
+ @Benchmark
+ public void writeHeaderAndRecords() throws Exception {
+ CountDownLatch latch = new CountDownLatch(recordCount * 100);
+ currentLatch.set(latch);
+
+ try {
+ fillHeader(fileId);
+// libaioFile.write(0L, BLOCK_SIZE, headerBuffer, callback);
+
+ for (int j = 0; j < 100; j++) {
+ for (int i = 0; i < recordCount; i++) {
+ updateRecord(recordBuffer, fileId, i);
+ long offset = BLOCK_SIZE + ((long) i * BLOCK_SIZE);
+ libaioFile.write(offset, BLOCK_SIZE, recordBuffer, callback);
+ }
+ }
+
+ latch.await();
+ } finally {
+ currentLatch.compareAndSet(latch, null);
+ }
+ }
+
+ private void fillHeader(long fileId) {
+ headerBuffer.putLong(0, fileId);
+ }
+
+ private void updateRecord(ByteBuffer buffer, long fileId, long recordId) {
+ buffer.putLong(0, fileId);
+ buffer.putLong(8, recordId);
+ }
+
+ private void initRecord(ByteBuffer record) {
+ while (record.position() < BLOCK_SIZE) {
+ record.put((byte) 1);
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@artemis.apache.org
For additional commands, e-mail: commits-help@artemis.apache.org