From c6abdddfe680efa56b8b4dba3e1d5f4cabeb5d0e Mon Sep 17 00:00:00 2001 From: Daniel Wu Date: Sat, 18 Nov 2023 21:08:20 +0800 Subject: [PATCH] deprecate jdk8 --- docs/1.xlsx | Bin 0 -> 21753 bytes docs/2.xlsx | Bin 0 -> 21622 bytes pom.xml | 10 +- src/benchmark/BaseWorker.java | 4 +- src/benchmark/Benchmark.java | 6 +- src/benchmark/BenchmarkCommons.java | 32 ++- src/benchmark/BenchmarkFastObjectPool.java | 14 +- .../BenchmarkFastObjectPoolDisruptor.java | 10 +- src/benchmark/BenchmarkFurious.java | 13 +- src/benchmark/BenchmarkResult.java | 30 ++- src/benchmark/BenchmarkStormpot.java | 22 +- src/benchmark/Start.java | 233 ++++++++++-------- .../cn/danielw/fop/DisruptorObjectPool.java | 6 + .../java/cn/danielw/fop/ObjectFactory.java | 6 + src/main/java/cn/danielw/fop/ObjectPool.java | 4 + 15 files changed, 223 insertions(+), 167 deletions(-) create mode 100644 docs/1.xlsx create mode 100644 docs/2.xlsx diff --git a/docs/1.xlsx b/docs/1.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..348e1fa0e7ff24b1837399307c5b5be3bb9a4cbe GIT binary patch literal 21753 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

GDj= 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.danielw fast-object-pool jar - 2.2.1 + 2.3.0 An extremely fast object pool with zero dependencies UTF-8 @@ -56,7 +56,7 @@ com.conversantmedia disruptor - 1.2.15 + 1.2.21 true @@ -99,8 +99,8 @@ maven-compiler-plugin 3.10.1 - 8 - 8 + 11 + 11 @@ -121,7 +121,7 @@ maven-javadoc-plugin 3.5.0 - 8 + 11 diff --git a/src/benchmark/BaseWorker.java b/src/benchmark/BaseWorker.java index d807c02..8424394 100644 --- a/src/benchmark/BaseWorker.java +++ b/src/benchmark/BaseWorker.java @@ -4,13 +4,15 @@ public abstract class BaseWorker extends Thread { private final int id; private final long loop; protected final int borrowsPerLoop; + protected int simulateBlockingMs; long err = 0; - public BaseWorker(Benchmark benchmark, int id, int borrowsPerLoop, long loop) { + public BaseWorker(Benchmark benchmark, int id, int borrowsPerLoop, long loop, int simulateBlockingMs) { this.benchmark = benchmark; this.id = id; this.loop = loop; this.borrowsPerLoop = borrowsPerLoop; + this.simulateBlockingMs = simulateBlockingMs; } @Override public void run() { diff --git a/src/benchmark/Benchmark.java b/src/benchmark/Benchmark.java index fbf6406..df1f7cd 100755 --- a/src/benchmark/Benchmark.java +++ b/src/benchmark/Benchmark.java @@ -42,7 +42,7 @@ public BenchmarkResult testAndPrint() throws InterruptedException { stats += statsAvgRespTime[i]; } double latency = stats / workerCount; - System.out.println("Average Response Time:" + new DecimalFormat("0.0000").format(latency)); +// System.out.println("Average Response Time:" + new DecimalFormat("0.0000").format(latency)); stats = 0; for (int i = 0; i < workerCount; i++) { @@ -52,10 +52,8 @@ public BenchmarkResult testAndPrint() throws InterruptedException { double throughput = (double) loop * workerCount / (t2 - t1); - System.out.println("Error Ratio:" + new DecimalFormat("0.00%").format(errRate)); System.out.println("Throughput Per Second:" + new DecimalFormat("0").format(throughput) + "K"); - System.out.println("Objects created:" + created.get()); - System.out.println(); +// System.out.println("Objects created:" + created.get()); return new BenchmarkResult(name, workerCount, borrowsPerLoop, loop, created.get(), errRate, throughput, latency); } diff --git a/src/benchmark/BenchmarkCommons.java b/src/benchmark/BenchmarkCommons.java index 49f1d82..d0d27ba 100755 --- a/src/benchmark/BenchmarkCommons.java +++ b/src/benchmark/BenchmarkCommons.java @@ -11,21 +11,31 @@ */ public class BenchmarkCommons extends Benchmark { - BenchmarkCommons(int workerCount, int borrowsPerLoop, int loop) throws Exception { + BenchmarkCommons(int workerCount, int borrowsPerLoop, int loop, int simulateBlockingMs) { super("common-pool", workerCount, borrowsPerLoop, loop); - GenericObjectPool pool = new GenericObjectPool<>(new PooledObjectFactory() { - @Override public PooledObject makeObject() throws Exception { + GenericObjectPool pool = new GenericObjectPool<>(new PooledObjectFactory<>() { + @Override + public PooledObject makeObject() { created.incrementAndGet(); return new DefaultPooledObject<>(new StringBuilder()); } - @Override public void destroyObject(PooledObject pooledObject) throws Exception { } + @Override + public void destroyObject(PooledObject pooledObject) { + } - @Override public boolean validateObject(PooledObject pooledObject) { return false; } + @Override + public boolean validateObject(PooledObject pooledObject) { + return false; + } - @Override public void activateObject(PooledObject pooledObject) throws Exception { } + @Override + public void activateObject(PooledObject pooledObject) { + } - @Override public void passivateObject(PooledObject pooledObject) throws Exception { } + @Override + public void passivateObject(PooledObject pooledObject) { + } }); pool.setMinIdle(256); pool.setMaxIdle(256); @@ -34,7 +44,7 @@ public class BenchmarkCommons extends Benchmark { this.workers = new Worker[workerCount]; for (int i = 0; i < workerCount; i++) { - workers[i] = new Worker(this, i, loop, borrowsPerLoop, pool); + workers[i] = new Worker(this, i, loop, borrowsPerLoop, simulateBlockingMs, pool); } } @@ -42,8 +52,8 @@ private static class Worker extends BaseWorker { private final GenericObjectPool pool; - Worker(Benchmark benchmark, int id, int loop, int borrowsPerLoop, GenericObjectPool pool) { - super(benchmark, id, borrowsPerLoop, loop); + Worker(Benchmark benchmark, int id, int loop, int borrowsPerLoop, int simulateBlockingMs, GenericObjectPool pool) { + super(benchmark, id, borrowsPerLoop, loop, simulateBlockingMs); this.pool = pool; } @@ -52,6 +62,8 @@ private static class Worker extends BaseWorker { try { for (int i = 0; i < borrowsPerLoop; i++) { StringBuilder obj = pool.borrowObject(10); + obj.append("X"); + if (simulateBlockingMs > 0) Thread.sleep(simulateBlockingMs); // simulate thread blocking list.add(obj); } } catch (Exception e) { diff --git a/src/benchmark/BenchmarkFastObjectPool.java b/src/benchmark/BenchmarkFastObjectPool.java index e294bdf..f2d86eb 100755 --- a/src/benchmark/BenchmarkFastObjectPool.java +++ b/src/benchmark/BenchmarkFastObjectPool.java @@ -11,17 +11,16 @@ */ public class BenchmarkFastObjectPool extends Benchmark { - BenchmarkFastObjectPool(String name, int workerCount, int borrows, int loop) throws InterruptedException { + BenchmarkFastObjectPool(String name, int workerCount, int borrows, int loop, int simulateBlockingMs) { super(name, workerCount, borrows, loop); PoolConfig config = new PoolConfig(); - config.setPartitionSize(16); + config.setPartitionSize(32); config.setMaxSize(16); config.setMinSize(16); config.setMaxIdleMilliseconds(60 * 1000 * 5); config.setMaxWaitMilliseconds(10); - - ObjectFactory factory = new ObjectFactory() { + ObjectFactory factory = new ObjectFactory<>() { @Override public StringBuilder create() { created.incrementAndGet(); @@ -38,7 +37,7 @@ public boolean validate(StringBuilder o) { ObjectPool pool = new ObjectPool<>(config, factory); workers = new Worker[workerCount]; for (int i = 0; i < workerCount; i++) { - workers[i] = new Worker(this, i, borrows, loop, pool); + workers[i] = new Worker(this, i, borrows, loop, simulateBlockingMs, pool); } } @@ -46,8 +45,8 @@ protected static class Worker extends BaseWorker { private final ObjectPool pool; - Worker(Benchmark benchmark, int id, int borrows, long loop, ObjectPool pool) { - super(benchmark, id, borrows, loop); + Worker(Benchmark benchmark, int id, int borrows, long loop, int simulateBlockingMs, ObjectPool pool) { + super(benchmark, id, borrows, loop, simulateBlockingMs); this.pool = pool; } @@ -57,6 +56,7 @@ protected static class Worker extends BaseWorker { for (int i = 0; i < borrowsPerLoop; i++) { Poolable obj = pool.borrowObject(false); obj.getObject().append("X"); + if (simulateBlockingMs > 0) Thread.sleep(simulateBlockingMs); // simulate thread blocking list.add(obj); } } catch (Exception e) { diff --git a/src/benchmark/BenchmarkFastObjectPoolDisruptor.java b/src/benchmark/BenchmarkFastObjectPoolDisruptor.java index 7056acc..beb9906 100755 --- a/src/benchmark/BenchmarkFastObjectPoolDisruptor.java +++ b/src/benchmark/BenchmarkFastObjectPoolDisruptor.java @@ -2,23 +2,21 @@ import cn.danielw.fop.ObjectFactory; import cn.danielw.fop.PoolConfig; -import java.util.concurrent.ThreadPoolExecutor; - /** * @author Daniel */ public class BenchmarkFastObjectPoolDisruptor extends Benchmark { - BenchmarkFastObjectPoolDisruptor(int workerCount, int borrows, int loop) throws InterruptedException { + BenchmarkFastObjectPoolDisruptor(int workerCount, int borrows, int loop, int simulateBlockingMs) { super("fop", workerCount, borrows, loop); PoolConfig config = new PoolConfig(); - config.setPartitionSize(16); + config.setPartitionSize(32); config.setMaxSize(16); config.setMinSize(16); config.setMaxIdleMilliseconds(60 * 1000 * 5); config.setMaxWaitMilliseconds(10); - ObjectFactory factory = new ObjectFactory() { + ObjectFactory factory = new ObjectFactory<>() { @Override public StringBuilder create() { created.incrementAndGet(); @@ -35,7 +33,7 @@ public boolean validate(StringBuilder o) { DisruptorObjectPool pool = new DisruptorObjectPool<>(config, factory); workers = new BenchmarkFastObjectPool.Worker[workerCount]; for (int i = 0; i < workerCount; i++) { - workers[i] = new BenchmarkFastObjectPool.Worker(this, i, borrows, loop, pool); + workers[i] = new BenchmarkFastObjectPool.Worker(this, i, borrows, loop, simulateBlockingMs, pool); } } diff --git a/src/benchmark/BenchmarkFurious.java b/src/benchmark/BenchmarkFurious.java index 238df0e..d0c30e3 100755 --- a/src/benchmark/BenchmarkFurious.java +++ b/src/benchmark/BenchmarkFurious.java @@ -1,5 +1,4 @@ import nf.fr.eraasoft.pool.ObjectPool; -import nf.fr.eraasoft.pool.PoolException; import nf.fr.eraasoft.pool.PoolSettings; import nf.fr.eraasoft.pool.PoolableObjectBase; @@ -11,16 +10,17 @@ */ public class BenchmarkFurious extends Benchmark { - BenchmarkFurious(int workerCount, int borrows, int loop) throws InterruptedException { + BenchmarkFurious(int workerCount, int borrows, int loop, int simulateBlockingMs) { super("furious", workerCount, borrows, loop); // Create your PoolSettings with an instance of PoolableObject - PoolSettings poolSettings = new PoolSettings<>(new PoolableObjectBase() { + PoolSettings poolSettings = new PoolSettings<>(new PoolableObjectBase<>() { @Override public StringBuilder make() { created.incrementAndGet(); return new StringBuilder(); } + @Override public void activate(StringBuilder t) { t.setLength(0); @@ -34,7 +34,7 @@ public void activate(StringBuilder t) { workers = new Worker[workerCount]; for (int i = 0; i < workerCount; i++) { - workers[i] = new Worker(this, i, borrows, loop, pool); + workers[i] = new Worker(this, i, borrows, loop, simulateBlockingMs, pool); } } @@ -42,8 +42,8 @@ private static class Worker extends BaseWorker { private final ObjectPool pool; - Worker(Benchmark benchmark, int id, int borrows, long loop, ObjectPool pool) { - super(benchmark, id, borrows, loop); + Worker(Benchmark benchmark, int id, int borrows, long loop, int simulateBlockingMs, ObjectPool pool) { + super(benchmark, id, borrows, loop, simulateBlockingMs); this.pool = pool; } @@ -53,6 +53,7 @@ private static class Worker extends BaseWorker { for (int i = 0; i < borrowsPerLoop; i++) { StringBuilder obj = pool.getObj(); // NO timeout at method level obj.append("X"); + if (simulateBlockingMs > 0) Thread.sleep(simulateBlockingMs); // simulate thread blocking list.add(obj); } } catch (Exception e) { diff --git a/src/benchmark/BenchmarkResult.java b/src/benchmark/BenchmarkResult.java index a37890c..51d9a30 100644 --- a/src/benchmark/BenchmarkResult.java +++ b/src/benchmark/BenchmarkResult.java @@ -24,17 +24,27 @@ public BenchmarkResult(String poolName, @Override public String toString() { - return poolName + - "," + threads + - "," + borrows + - "," + loops + - "," + created + - "," + plotLegend() + - "," + errorRate + - "," + avgThroughput; +// return poolName + +// "," + threads + +// "," + borrows + +// "," + loops + +// "," + created + +// "," + plotLegend() + +// "," + errorRate + +// "," + avgThroughput; + return threads + "/" + poolName + "," + errorRate + "," + avgThroughput; } - private String plotLegend() { - return poolName + "/" + threads; + public String getPoolName() { + return poolName; } + + public double getErrorRate() { + return errorRate; + } + + public double getAvgThroughput() { + return avgThroughput; + } + } diff --git a/src/benchmark/BenchmarkStormpot.java b/src/benchmark/BenchmarkStormpot.java index 1e45598..1a96c51 100755 --- a/src/benchmark/BenchmarkStormpot.java +++ b/src/benchmark/BenchmarkStormpot.java @@ -36,34 +36,25 @@ public void release() { } - BenchmarkStormpot(int workerCount, int borrows, int loop) throws InterruptedException { + BenchmarkStormpot(int workerCount, int borrows, int loop, int simulateBlockingMs) { super("Stormpot", workerCount, borrows, loop); Config config = new Config<>().setAllocator(new Allocator() { @Override - public MyPoolable allocate(Slot slot) throws Exception { + public MyPoolable allocate(Slot slot) { created.incrementAndGet(); return new MyPoolable(slot); } @Override - public void deallocate(MyPoolable x) throws Exception { + public void deallocate(MyPoolable x) { } }).setSize(256); - /* - config.setExpiration(new Expiration() { - @Override - public boolean hasExpired(SlotInfo slotInfo) throws Exception { - // how to support max idle? - return slotInfo.getAgeMillis() > 60 * 10000 * 5; - } - }); - */ Pool pool = new BlazePool<>(config); workers = new Worker[workerCount]; for (int i = 0; i < workerCount; i++) { - workers[i] = new Worker(this, i, borrows, loop, pool); + workers[i] = new Worker(this, i, borrows, loop, simulateBlockingMs, pool); } System.out.println("slots:" + slots.size()); } @@ -73,8 +64,8 @@ private static class Worker extends BaseWorker { private static final Timeout TIMEOUT = new Timeout(10, TimeUnit.MILLISECONDS); private final Pool pool; - Worker(Benchmark benchmark, int id, int borrows, int loop, Pool pool) { - super(benchmark, id, borrows, loop); + Worker(Benchmark benchmark, int id, int borrows, int loop, int simulateBlockingMs, Pool pool) { + super(benchmark, id, borrows, loop, simulateBlockingMs); this.pool = pool; } @@ -84,6 +75,7 @@ private static class Worker extends BaseWorker { for (int i = 0; i < borrowsPerLoop; i++) { MyPoolable obj = pool.claim(TIMEOUT); obj.getTest().append("x"); + if (simulateBlockingMs > 0) Thread.sleep(simulateBlockingMs); // simulate thread blocking list.add(obj); } } catch (Exception e) { diff --git a/src/benchmark/Start.java b/src/benchmark/Start.java index a303e78..f676573 100644 --- a/src/benchmark/Start.java +++ b/src/benchmark/Start.java @@ -1,163 +1,190 @@ -import java.util.ArrayList; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; public class Start { - private static List csvLines = new ArrayList<>(); + // key: threads + // value: pool-name and throughput + private static final Map> throughputByThreads = new TreeMap<>(); + // key: threads + // value: pool-name and error rate + private static final Map> errorRateByThreads = new TreeMap<>(); public static void main(String[] args) throws Exception { - + int simulateBlockingMs = 0; System.out.println("-----------warm up------------"); -// testFOP(50, 1, 1000); - testFOPDisruptor(50, 1, 1000); - testStormpot(50, 1, 1000); - testFurious(50, 1, 1000); - testCommon(50, 1, 1000); - csvLines.clear(); +// testFOP(50, 1, 1000, simulateBlockingMs); + testFOPDisruptor(50, 1, 1000, simulateBlockingMs); + testStormpot(50, 1, 1000, simulateBlockingMs); + testFurious(50, 1, 1000, simulateBlockingMs); + testCommon(50, 1, 1000, simulateBlockingMs); System.out.println("-----------warm up done, start test ------------"); -// testAll(1); -// printResult(csvLines); - testAll(2); - printResult(csvLines); + + System.out.println("----------- borrow 1 ------------"); + throughputByThreads.clear(); + testAll(1, simulateBlockingMs); + printResult(); + + System.out.println("----------- borrow 2 ------------"); + throughputByThreads.clear(); + testAll(2, simulateBlockingMs); + printResult(); + System.exit(0); } - private static void printResult(List csvLines) { - System.out.println("name,threads,borrows,loops,pool size,legend,error rate,throughput"); - csvLines.forEach(System.out::println); - System.out.println(); + private static void printResult() { + List poolNames = new ArrayList<>(throughputByThreads.values().stream().findFirst().get().keySet()); + System.out.println("throughput result:"); + System.out.println("threads," + poolNames); + throughputByThreads.forEach((threads, value) -> { + System.out.print(threads + ","); + poolNames.forEach(name -> System.out.print(value.getOrDefault(name, 0D) + ",")); + System.out.println(); + }); + + System.out.println("error rate result:"); + System.out.println("threads," + poolNames); + errorRateByThreads.forEach((threads, value) -> { + System.out.print(threads + ","); + poolNames.forEach(name -> System.out.print(value.getOrDefault(name, 0D) + ",")); + System.out.println(); + }); } - private static void testAll(int borrows) throws Exception { -// System.out.println("-----------fast object pool (borrow " + borrows + " objects per time)------------"); + private static void testAll(int borrows, int simulateBlockingMs) throws Exception { +// System.out.println("-----------fast object pool (borrow " + borrows + " objects each time)------------"); // testFOP(borrows); + System.out.println("-----------fast object pool with disruptor (borrow " + borrows + " object each time)------------"); + testFOPDisruptor(borrows, simulateBlockingMs); - System.out.println("-----------fast object pool with disruptor (borrow " + borrows + " object per time)------------"); - testFOPDisruptor(borrows); - - System.out.println("-----------stormpot object pool (borrow " + borrows + " object per time)------------"); - testStormpot(borrows); - - System.out.println("-----------furious object pool (borrow " + borrows + " object per time)------------"); - testFurious(borrows); + System.out.println("-----------stormpot object pool (borrow " + borrows + " object each time)------------"); + testStormpot(borrows, simulateBlockingMs); - System.out.println("------------Apache commons pool (borrow " + borrows + " object per time)-----------"); - testCommon(borrows); + System.out.println("-----------furious object pool (borrow " + borrows + " object each time)------------"); + testFurious(borrows, simulateBlockingMs); + System.out.println("------------Apache commons pool (borrow " + borrows + " object each time)-----------"); + testCommon(borrows, simulateBlockingMs); } - private static void testCommon(int borrows) throws Exception { + private static void testCommon(int borrows, int simulateBlockingMs) throws Exception { // too slow, so less loops - testCommon(50, borrows, 20000); - testCommon(100, borrows, 10000); -// testCommon(150, borrows, 9000); - testCommon(200, borrows, 8000); -// testCommon(250, borrows, 7000); -// testCommon(300, borrows, 6000); -// testCommon(350, borrows, 5000); - testCommon(400, borrows, 4000); -// testCommon(450, borrows, 3000); -// testCommon(500, borrows, 2000); -// testCommon(550, borrows, 1000); - testCommon(600, borrows, 1000); + testCommon(50, borrows, 20000, simulateBlockingMs); + testCommon(100, borrows, 10000, simulateBlockingMs); +// testCommon(150, borrows, 9000, simulateBlockingMs); + testCommon(200, borrows, 8000, simulateBlockingMs); +// testCommon(250, borrows, 7000, simulateBlockingMs); +// testCommon(300, borrows, 6000, simulateBlockingMs); +// testCommon(350, borrows, 5000, simulateBlockingMs); + testCommon(400, borrows, 4000, simulateBlockingMs); +// testCommon(450, borrows, 3000, simulateBlockingMs); +// testCommon(500, borrows, 2000, simulateBlockingMs); +// testCommon(550, borrows, 1000, simulateBlockingMs); + testCommon(600, borrows, 1000, simulateBlockingMs); } - private static void testFurious(int borrows) throws InterruptedException { + private static void testFurious(int borrows, int simulateBlockingMs) throws InterruptedException { if (borrows > 1) { System.out.println("Furious cannot set max wait time, so it will hang with deadlock if get more than 1 object concurrently"); return; } - testFurious(50, borrows, 50000); - testFurious(100, borrows, 50000); -// testFurious(150, borrows, 50000); - testFurious(200, borrows, 30000); -// testFurious(250, borrows, 30000); -// testFurious(300, borrows, 30000); -// testFurious(350, borrows, 20000); - testFurious(400, borrows, 20000); -// testFurious(450, borrows, 20000); -// testFurious(500, borrows, 10000); -// testFurious(550, borrows, 10000); - testFurious(600, borrows, 10000); + testFurious(50, borrows, 50000, simulateBlockingMs); + testFurious(100, borrows, 50000, simulateBlockingMs); +// testFurious(150, borrows, 50000, simulateBlockingMs); + testFurious(200, borrows, 30000, simulateBlockingMs); +// testFurious(250, borrows, 30000, simulateBlockingMs); +// testFurious(300, borrows, 30000, simulateBlockingMs); +// testFurious(350, borrows, 20000, simulateBlockingMs); + testFurious(400, borrows, 20000, simulateBlockingMs); +// testFurious(450, borrows, 20000, simulateBlockingMs); +// testFurious(500, borrows, 10000, simulateBlockingMs); +// testFurious(550, borrows, 10000, simulateBlockingMs); + testFurious(600, borrows, 10000, simulateBlockingMs); } - private static void testStormpot(int borrows) throws InterruptedException { - testStormpot(50, borrows, 50000); - testStormpot(100, borrows, 50000); + private static void testStormpot(int borrows, int simulateBlockingMs) throws InterruptedException { + testStormpot(50, borrows, 50000, simulateBlockingMs); + testStormpot(100, borrows, 50000, simulateBlockingMs); // testStormpot(150, borrows, 50000); if (borrows > 1) { return; // this is too slow, skip it } - testStormpot(200, borrows, 30000); + testStormpot(200, borrows, 30000, simulateBlockingMs); // testStormpot(250, borrows, 30000); // testStormpot(300, borrows, 30000); // testStormpot(350, borrows, 20000); - testStormpot(400, borrows, 20000); + testStormpot(400, borrows, 20000, simulateBlockingMs); // testStormpot(450, borrows, 20000); // testStormpot(500, borrows, 10000); // testStormpot(550, borrows, 10000); - testStormpot(600, borrows, 10000); + testStormpot(600, borrows, 10000, simulateBlockingMs); } - private static void testFOP(int borrowsPerLoop) throws InterruptedException { - testFOP(50, borrowsPerLoop, 50000); - testFOP(100, borrowsPerLoop, 50000); - testFOP(150, borrowsPerLoop, 50000); - testFOP(200, borrowsPerLoop, 30000); - testFOP(250, borrowsPerLoop, 30000); - testFOP(300, borrowsPerLoop, 30000); - testFOP(350, borrowsPerLoop, 20000); - testFOP(400, borrowsPerLoop, 20000); - testFOP(450, borrowsPerLoop, 20000); - testFOP(500, borrowsPerLoop, 10000); - testFOP(550, borrowsPerLoop, 10000); - testFOP(600, borrowsPerLoop, 10000); + private static void testFOP(int borrowsPerLoop, int simulateBlockingMs) throws InterruptedException { + testFOP(50, borrowsPerLoop, 50000, simulateBlockingMs); + testFOP(100, borrowsPerLoop, 50000, simulateBlockingMs); + testFOP(150, borrowsPerLoop, 50000, simulateBlockingMs); + testFOP(200, borrowsPerLoop, 30000, simulateBlockingMs); + testFOP(250, borrowsPerLoop, 30000, simulateBlockingMs); + testFOP(300, borrowsPerLoop, 30000, simulateBlockingMs); + testFOP(350, borrowsPerLoop, 20000, simulateBlockingMs); + testFOP(400, borrowsPerLoop, 20000, simulateBlockingMs); + testFOP(450, borrowsPerLoop, 20000, simulateBlockingMs); + testFOP(500, borrowsPerLoop, 10000, simulateBlockingMs); + testFOP(550, borrowsPerLoop, 10000, simulateBlockingMs); + testFOP(600, borrowsPerLoop, 10000, simulateBlockingMs); } - private static void testFOPDisruptor(int borrows) throws InterruptedException { - testFOPDisruptor(50, borrows, 50000); - testFOPDisruptor(100,borrows, 50000); -// testFOPDisruptor(150,borrows, 50000); - testFOPDisruptor(200,borrows, 30000); -// testFOPDisruptor(250,borrows, 30000); -// testFOPDisruptor(300,borrows, 30000); -// testFOPDisruptor(350,borrows, 20000); - testFOPDisruptor(400,borrows, 20000); -// testFOPDisruptor(450,borrows, 20000); -// testFOPDisruptor(500,borrows, 10000); -// testFOPDisruptor(550,borrows, 10000); - testFOPDisruptor(600,borrows, 10000); + private static void testFOPDisruptor(int borrows, int simulateBlockingMs) throws InterruptedException { + testFOPDisruptor(50, borrows, 50000, simulateBlockingMs); + testFOPDisruptor(100,borrows, 50000, simulateBlockingMs); +// testFOPDisruptor(150,borrows, 50000, simulateBlockingMs); + testFOPDisruptor(200,borrows, 30000, simulateBlockingMs); +// testFOPDisruptor(250,borrows, 30000, simulateBlockingMs); +// testFOPDisruptor(300,borrows, 30000, simulateBlockingMs); +// testFOPDisruptor(350,borrows, 20000, simulateBlockingMs); + testFOPDisruptor(400,borrows, 20000, simulateBlockingMs); +// testFOPDisruptor(450,borrows, 20000, simulateBlockingMs); +// testFOPDisruptor(500,borrows, 10000, simulateBlockingMs); +// testFOPDisruptor(550,borrows, 10000, simulateBlockingMs); + testFOPDisruptor(600,borrows, 10000, simulateBlockingMs); } - private static void testFOP(int workerCount, int borrowsPerLoop, int loop) throws InterruptedException { - BenchmarkResult result = new BenchmarkFastObjectPool("fop-nod", workerCount, borrowsPerLoop, loop).testAndPrint(); - csvLines.add(result.toString()); + private static void testFOP(int workerCount, int borrowsPerLoop, int loop, int simulateBlockingMs) throws InterruptedException { + BenchmarkResult result = new BenchmarkFastObjectPool("fop-nod", workerCount, borrowsPerLoop, loop, simulateBlockingMs).testAndPrint(); + throughputByThreads.computeIfAbsent(workerCount, k -> new TreeMap<>()).put(result.getPoolName(), result.getAvgThroughput()); + errorRateByThreads.computeIfAbsent(workerCount, k -> new TreeMap<>()).put(result.getPoolName(), result.getErrorRate()); cleanup(); } - private static void testFOPDisruptor(int workerCount, int borrowsPerLoop, int loop) throws InterruptedException { - BenchmarkResult result = new BenchmarkFastObjectPoolDisruptor(workerCount, borrowsPerLoop, loop).testAndPrint(); - csvLines.add(result.toString()); + private static void testFOPDisruptor(int workerCount, int borrowsPerLoop, int loop, int simulateBlockingMs) throws InterruptedException { + BenchmarkResult result = new BenchmarkFastObjectPoolDisruptor(workerCount, borrowsPerLoop, loop, simulateBlockingMs).testAndPrint(); + throughputByThreads.computeIfAbsent(workerCount, k -> new TreeMap<>()).put(result.getPoolName(), result.getAvgThroughput()); + errorRateByThreads.computeIfAbsent(workerCount, k -> new TreeMap<>()).put(result.getPoolName(), result.getErrorRate()); cleanup(); } - private static void testStormpot(int workerCount, int borrowsPerLoop, int loop) throws InterruptedException { - BenchmarkResult result = new BenchmarkStormpot(workerCount, borrowsPerLoop, loop).testAndPrint(); - csvLines.add(result.toString()); + private static void testStormpot(int workerCount, int borrowsPerLoop, int loop, int simulateBlockingMs) throws InterruptedException { + BenchmarkResult result = new BenchmarkStormpot(workerCount, borrowsPerLoop, loop, simulateBlockingMs).testAndPrint(); + throughputByThreads.computeIfAbsent(workerCount, k -> new TreeMap<>()).put(result.getPoolName(), result.getAvgThroughput()); + errorRateByThreads.computeIfAbsent(workerCount, k -> new TreeMap<>()).put(result.getPoolName(), result.getErrorRate()); cleanup(); } - private static void testFurious(int workerCount, int borrowsPerLoop, int loop) throws InterruptedException { - BenchmarkResult result = new BenchmarkFurious(workerCount, borrowsPerLoop, loop).testAndPrint(); - csvLines.add(result.toString()); + private static void testFurious(int workerCount, int borrowsPerLoop, int loop, int simulateBlockingMs) throws InterruptedException { + BenchmarkResult result = new BenchmarkFurious(workerCount, borrowsPerLoop, loop, simulateBlockingMs).testAndPrint(); + throughputByThreads.computeIfAbsent(workerCount, k -> new TreeMap<>()).put(result.getPoolName(), result.getAvgThroughput()); + errorRateByThreads.computeIfAbsent(workerCount, k -> new TreeMap<>()).put(result.getPoolName(), result.getErrorRate()); cleanup(); } - private static void testCommon(int workerCount, int borrowsPerLoop, int loop) throws Exception { - BenchmarkResult result = new BenchmarkCommons(workerCount, borrowsPerLoop, loop).testAndPrint(); - csvLines.add(result.toString()); + private static void testCommon(int workerCount, int borrowsPerLoop, int loop, int simulateBlockingMs) throws Exception { + BenchmarkResult result = new BenchmarkCommons(workerCount, borrowsPerLoop, loop, simulateBlockingMs).testAndPrint(); + throughputByThreads.computeIfAbsent(workerCount, k -> new TreeMap<>()).put(result.getPoolName(), result.getAvgThroughput()); + errorRateByThreads.computeIfAbsent(workerCount, k -> new TreeMap<>()).put(result.getPoolName(), result.getErrorRate()); cleanup(); } diff --git a/src/main/java/cn/danielw/fop/DisruptorObjectPool.java b/src/main/java/cn/danielw/fop/DisruptorObjectPool.java index 8e9300d..2e6a8f2 100644 --- a/src/main/java/cn/danielw/fop/DisruptorObjectPool.java +++ b/src/main/java/cn/danielw/fop/DisruptorObjectPool.java @@ -9,10 +9,16 @@ */ public class DisruptorObjectPool extends ObjectPool { + /** + * build a disruptor-based pool for better performance. + */ public DisruptorObjectPool(PoolConfig poolConfig, ObjectFactory objectFactory) { super(poolConfig, objectFactory); } + /** + * create a disruptor-based blocking queue for better performance + */ @Override protected BlockingQueue> createBlockingQueue(PoolConfig config) { return new DisruptorBlockingQueue<>(config.getMaxSize()); diff --git a/src/main/java/cn/danielw/fop/ObjectFactory.java b/src/main/java/cn/danielw/fop/ObjectFactory.java index 3d3662a..fc395b7 100755 --- a/src/main/java/cn/danielw/fop/ObjectFactory.java +++ b/src/main/java/cn/danielw/fop/ObjectFactory.java @@ -10,8 +10,14 @@ public interface ObjectFactory { */ T create(); + /** + * destroy the object gracefully. + */ void destroy(T t); + /** + * validate the object before returning to the consumer. Note, the validation must be fast + */ boolean validate(T t); } diff --git a/src/main/java/cn/danielw/fop/ObjectPool.java b/src/main/java/cn/danielw/fop/ObjectPool.java index 3715b4f..41bfbc8 100755 --- a/src/main/java/cn/danielw/fop/ObjectPool.java +++ b/src/main/java/cn/danielw/fop/ObjectPool.java @@ -32,6 +32,10 @@ public ObjectPool(PoolConfig poolConfig, ObjectFactory objectFactory) { } } + /** + * the pool needs a blocking queue for consumers to wait for an available object. The queue can be in different + * implementations in subclasses. + */ protected BlockingQueue> createBlockingQueue(PoolConfig poolConfig) { return new ArrayBlockingQueue<>(poolConfig.getMaxSize()); }