[ISSUE #10020] test efficiency of MemorySafeLinkedBlockingQueue (#11841)

This commit is contained in:
fan 2023-03-27 19:14:20 +08:00 committed by GitHub
parent 5a2114d140
commit 89e271408d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 58 additions and 2 deletions

View File

@ -17,13 +17,14 @@
package org.apache.dubbo.common.threadpool;
import net.bytebuddy.agent.ByteBuddyAgent;
import org.apache.dubbo.common.concurrent.AbortPolicy;
import org.apache.dubbo.common.concurrent.RejectException;
import net.bytebuddy.agent.ByteBuddyAgent;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.lang.instrument.Instrumentation;
import java.util.concurrent.LinkedBlockingQueue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
@ -55,4 +56,59 @@ class MemorySafeLinkedBlockingQueueTest {
assertThrows(RejectException.class, () -> queue.offer(() -> {
}));
}
@Test
void testEfficiency() throws InterruptedException {
// if length is vert large(unit test may runs for a long time), so you may need to modify JVM param such as : -Xms=1024m -Xmx=2048m
// if you want to test efficiency of MemorySafeLinkedBlockingQueue, you may modify following param: length and times
int length = 1000, times = 1;
// LinkedBlockingQueue insert Integer: 500W * 20 times
long spent1 = spend(new LinkedBlockingQueue<>(), length, times);
// MemorySafeLinkedBlockingQueue insert Integer: 500W * 20 times
long spent2 = spend(newMemorySafeLinkedBlockingQueue(), length, times);
System.gc();
System.out.println(String.format("LinkedBlockingQueue spent %s millis, MemorySafeLinkedBlockingQueue spent %s millis", spent1, spent2));
// efficiency between LinkedBlockingQueue and MemorySafeLinkedBlockingQueue is very nearly the same
Assertions.assertTrue(spent1 - spent2 <= 1);
}
private static long spend(LinkedBlockingQueue<Integer> lbq, int length, int times) throws InterruptedException {
// new Queue
if (lbq instanceof MemorySafeLinkedBlockingQueue) {
lbq = newMemorySafeLinkedBlockingQueue();
} else {
lbq = new LinkedBlockingQueue<>();
}
long total = 0L;
for (int i = 0; i < times; i++) {
long start = System.currentTimeMillis();
for (int j = 0; j < length; j++) {
lbq.offer(j);
}
long end = System.currentTimeMillis();
long spent = end - start;
total += spent;
}
long result = total / times;
// gc
System.gc();
return result;
}
private static MemorySafeLinkedBlockingQueue<Integer> newMemorySafeLinkedBlockingQueue() {
ByteBuddyAgent.install();
final Instrumentation instrumentation = ByteBuddyAgent.getInstrumentation();
final long objectSize = instrumentation.getObjectSize((Runnable) () -> { });
int maxFreeMemory = (int) MemoryLimitCalculator.maxAvailable();
MemorySafeLinkedBlockingQueue<Integer> queue = new MemorySafeLinkedBlockingQueue<>(maxFreeMemory);
queue.setMaxFreeMemory((int) (MemoryLimitCalculator.maxAvailable() - objectSize));
queue.setRejector(new AbortPolicy<>());
return queue;
}
}