CoralStore can write a 256-byte message to disk in around 159 nanoseconds through the FileStore
implementation. Moreover, by using the AsyncStore
you can get even lower latencies (60 nanoseconds) and variance, as the numbers on this article demonstrate.
The machine used for the benchmarks below was an Intel i7 quad-core (4 x 3.50GHz) Ubuntu box overclocked to 4.50Ghz.
FileStore
With a FileStore
you can persist all your messages to disk. As the example below demonstrates, a FileStore
by itself (i.e. without being asynchronous) is already very fast, but has some outliers as you can see in the 99.9 percentile:
Messages: 900,000 (256 bytes) Avg Time: 159.06 nanos Min Time: 47.0 nanos Max Time: 98.944 micros 75% = [avg: 51.0 nanos, max: 53.0 nanos] 90% = [avg: 51.0 nanos, max: 55.0 nanos] 99% = [avg: 53.0 nanos, max: 174.0 nanos] 99.9% = [avg: 132.0 nanos, max: 25.571 micros] 99.99% = [avg: 155.0 nanos, max: 27.549 micros] 99.999% = [avg: 158.0 nanos, max: 38.035 micros]
AsyncStore
With the AsyncStore
you can get blazing fast performance with no outliers as you can see by the results below:
Messages: 900,000 (256 bytes) Avg Time: 59.84 nanos Min Time: 41.0 nanos Max Time: 10.221 micros 75% = [avg: 49.0 nanos, max: 71.0 nanos] 90% = [avg: 54.0 nanos, max: 84.0 nanos] 99% = [avg: 58.0 nanos, max: 176.0 nanos] 99.9% = [avg: 59.0 nanos, max: 388.0 nanos] 99.99% = [avg: 59.0 nanos, max: 476.0 nanos] 99.999% = [avg: 59.0 nanos, max: 1.748 micros]
FileStore Benchmark Source Code
package com.coralblocks.coralstore.bench; import java.io.IOException; import java.nio.ByteBuffer; import com.coralblocks.coralbits.bench.Benchmarker; import com.coralblocks.coralstore.FileStore; import com.coralblocks.coralstore.Store; import com.coralblocks.coralthreads.Affinity; public class FileBench { public static void main(String[] args) throws IOException { // java -server -verbose:gc -cp target/coralstore-all.jar:lib/jna-3.5.1.jar -DdetailedBenchmarker=true -Xms2g -Xmx8g -XX:NewSize=512m -XX:MaxNewSize=1024m com.coralblocks.coralstore.bench.FileBench 256 100000 1000000 2 int msgSize = Integer.parseInt(args[0]); int warmup = Integer.parseInt(args[1]); int messages = Integer.parseInt(args[2]); int procToBind = args.length > 3 ? Integer.parseInt(args[3]) : -1; byte[] msgBytes = new byte[msgSize]; // build a dummy message: for(int i = 0; i < msgBytes.length; i++) { msgBytes[i] = (byte) String.valueOf(i % 10).charAt(0); } ByteBuffer msg = ByteBuffer.wrap(msgBytes); Store store = new FileStore(".", "fileStoreSession"); Benchmarker bench = Benchmarker.create(warmup); if (procToBind != -1) { System.out.println("Using affinity! procToBind=" + procToBind + " available=" + Affinity.isAvailable()); Affinity.assignToProcessor(procToBind, Thread.currentThread()); Affinity.bind(); } for(int i = 0; i < messages; i++) { msg.position(0); bench.mark(); store.addMessage(msg); store.flush(); bench.measure(); } store.close(); bench.printResults(); } }
AsyncStore Benchmark Source Code
package com.coralblocks.coralstore.bench; import java.io.IOException; import java.nio.ByteBuffer; import com.coralblocks.coralbits.bench.Benchmarker; import com.coralblocks.coralstore.FileStore; import com.coralblocks.coralstore.Store; import com.coralblocks.coralstore.async.AsyncStore; import com.coralblocks.coralthreads.Affinity; public class AsyncBench { public static void main(String[] args) throws IOException, InterruptedException { // java -server -verbose:gc -cp target/coralstore-all.jar:lib/jna-3.5.1.jar -DdetailedBenchmarker=true -DcoralThreadsVerbose=true -Xms2g -Xmx8g -XX:NewSize=512m -XX:MaxNewSize=1024m com.coralblocks.coralstore.bench.AsyncBench 256 100000 1000000 2 3 int msgSize = Integer.parseInt(args[0]); int warmup = Integer.parseInt(args[1]); int messages = Integer.parseInt(args[2]); int procToBind = args.length > 3 ? Integer.parseInt(args[3]) : -1; int procToBindAsync = args.length > 4 ? Integer.parseInt(args[4]) : -1; byte[] msgBytes = new byte[msgSize]; // build a dummy message: for(int i = 0; i < msgBytes.length; i++) { msgBytes[i] = (byte) String.valueOf(i % 10).charAt(0); } ByteBuffer msg = ByteBuffer.wrap(msgBytes); Store store = new FileStore(".", "asyncStoreSession"); AsyncStore asyncStore = new AsyncStore(store, msgSize, procToBindAsync); Benchmarker bench = Benchmarker.create(warmup); if (procToBind != -1) { Affinity.assignToProcessor(procToBind, Thread.currentThread()); Affinity.bind(); } for(int i = 0; i < messages; i++) { msg.position(0); bench.mark(); asyncStore.addMessage(msg); asyncStore.flush(); bench.measure(); if ((i + 1) % AsyncStore.getQueueCapacity() == 0) { // avoid queue contention because we are measuring latency, not throughput asyncStore.drainAndWait(); } } asyncStore.discard(); bench.printResults(); } }
Conclusion
CoralStore delivers blazing fast performance with very low latency and variance. You can persist messages in 70 nanoseconds on average.