diff --git a/java/benchmarks/build.gradle b/java/benchmarks/build.gradle index 8d9e500284..5e22fda5c7 100644 --- a/java/benchmarks/build.gradle +++ b/java/benchmarks/build.gradle @@ -18,6 +18,10 @@ dependencies { implementation 'io.lettuce:lettuce-core:6.2.6.RELEASE' implementation 'commons-cli:commons-cli:1.5.0' implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.13.0' + implementation group: 'com.google.code.gson', name: 'gson', version: '2.10.1' + + compileOnly 'org.projectlombok:lombok:1.18.30' + annotationProcessor 'org.projectlombok:lombok:1.18.30' } // Apply a specific Java toolchain to ease working on different environments. diff --git a/java/benchmarks/src/main/java/javababushka/benchmarks/BenchmarkingApp.java b/java/benchmarks/src/main/java/javababushka/benchmarks/BenchmarkingApp.java index 66ea1f5029..fc57dff2ce 100644 --- a/java/benchmarks/src/main/java/javababushka/benchmarks/BenchmarkingApp.java +++ b/java/benchmarks/src/main/java/javababushka/benchmarks/BenchmarkingApp.java @@ -2,11 +2,8 @@ import static javababushka.benchmarks.utils.Benchmarking.testClientSetGet; -import java.io.FileWriter; -import java.io.IOException; import java.util.Arrays; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; import javababushka.benchmarks.jedis.JedisClient; @@ -57,14 +54,6 @@ public static void main(String[] args) { break; } } - - if (runConfiguration.resultsFile.isPresent()) { - try { - runConfiguration.resultsFile.get().close(); - } catch (IOException ioException) { - System.out.println("Error closing results file"); - } - } } private static Options getOptions() { @@ -97,12 +86,7 @@ private static RunConfiguration verifyOptions(CommandLine line) throws ParseExce } if (line.hasOption("resultsFile")) { - try { - runConfiguration.resultsFile = - Optional.of(new FileWriter(line.getOptionValue("resultsFile"))); - } catch (IOException e) { - throw new ParseException("Unable to write to resultsFile."); - } + runConfiguration.resultsFile = line.getOptionValue("resultsFile"); } if (line.hasOption("dataSize")) { @@ -210,8 +194,8 @@ public boolean isEqual(String other) { public static class RunConfiguration { public String configuration; - public Optional resultsFile; public int dataSize; + public String resultsFile; public List concurrentTasks; public ClientName[] clients; public String host; @@ -222,9 +206,9 @@ public static class RunConfiguration { public RunConfiguration() { configuration = "Release"; - resultsFile = Optional.empty(); + resultsFile = "___.json"; // null; dataSize = 20; - concurrentTasks = List.of(10, 100); + concurrentTasks = List.of(10); // , 100); clients = new ClientName[] { // ClientName.BABUSHKA, @@ -232,7 +216,7 @@ public RunConfiguration() { }; host = "localhost"; port = 6379; - clientCount = new int[] {1, 2}; + clientCount = new int[] {1 /*, 2*/}; tls = false; } } diff --git a/java/benchmarks/src/main/java/javababushka/benchmarks/utils/Benchmarking.java b/java/benchmarks/src/main/java/javababushka/benchmarks/utils/Benchmarking.java index bae34c9373..9cf567659f 100644 --- a/java/benchmarks/src/main/java/javababushka/benchmarks/utils/Benchmarking.java +++ b/java/benchmarks/src/main/java/javababushka/benchmarks/utils/Benchmarking.java @@ -1,12 +1,10 @@ package javababushka.benchmarks.utils; -import java.io.FileWriter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -49,7 +47,7 @@ public interface Operation { void go() throws Exception; } - private static Pair getLatency(Map actions) { + public static Pair getLatency(Map actions) { var action = randomAction(); long before = System.nanoTime(); try { @@ -107,32 +105,6 @@ public static Map calculateResults( return results; } - public static void printResults( - Map calculatedResults, Optional resultsFile) { - if (resultsFile.isPresent()) { - printResults(calculatedResults, resultsFile.get()); - } else { - printResults(calculatedResults); - } - } - - public static void printResults( - Map resultsMap, FileWriter resultsFile) { - for (Map.Entry entry : resultsMap.entrySet()) { - ChosenAction action = entry.getKey(); - LatencyResults results = entry.getValue(); - - try { - resultsFile.write("Avg. time in ms per " + action + ": " + results.avgLatency / 1000000.0); - resultsFile.write(action + " p50 latency in ms: " + results.p50Latency / 1000000.0); - resultsFile.write(action + " p90 latency in ms: " + results.p90Latency / 1000000.0); - resultsFile.write(action + " p99 latency in ms: " + results.p99Latency / 1000000.0); - resultsFile.write(action + " std dev in ms: " + results.stdDeviation / 1000000.0); - } catch (Exception ignored) { - } - } - } - public static void printResults(Map resultsMap) { for (Map.Entry entry : resultsMap.entrySet()) { ChosenAction action = entry.getKey(); @@ -199,6 +171,7 @@ public static void testClientSetGet( "===> concurrentNum = %d, clientNum = %d, tasks = %d%n", concurrentNum, clientNum, tasks.size()); } + long started = System.nanoTime(); tasks.stream() .map(CompletableFuture::runAsync) .forEach( @@ -210,7 +183,18 @@ public static void testClientSetGet( } }); - printResults(calculateResults(actionResults), config.resultsFile); + var calculatedResults = calculateResults(actionResults); + if (config.resultsFile != null) { + Reporting.WriteJson( + calculatedResults, + config.resultsFile, + config.dataSize, + clientCreator.get().getName(), + clientNum, + concurrentNum, + iterationCounter.get() * 1e9 / (System.nanoTime() - started)); + } + printResults(calculatedResults); } } diff --git a/java/benchmarks/src/main/java/javababushka/benchmarks/utils/Reporting.java b/java/benchmarks/src/main/java/javababushka/benchmarks/utils/Reporting.java new file mode 100644 index 0000000000..1f14613bc7 --- /dev/null +++ b/java/benchmarks/src/main/java/javababushka/benchmarks/utils/Reporting.java @@ -0,0 +1,102 @@ +package javababushka.benchmarks.utils; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; +import lombok.Getter; + +public class Reporting { + + public static void WriteJson( + Map calculatedResults, + String resultsFile, + int dataSize, + String client, + int clientCount, + int numOfTasks, + double tps) { + + try { + Gson gson = new GsonBuilder().setPrettyPrinting().serializeNulls().create(); + Collection recordings = new ArrayList<>(); + + Path path = Path.of(resultsFile); + if (Files.exists(path)) { + TypeToken> collectionType = new TypeToken<>() {}; + var json = new String(Files.readAllBytes(path)); + recordings = gson.fromJson(json, collectionType); + } + var data = new Measurements(); + data.data_size = dataSize; + data.client = client; + data.clientCount = clientCount; + data.num_of_tasks = numOfTasks; + data.tps = tps; + // TODO: is_cluster + + data.get_existing_average_latency = + calculatedResults.get(ChosenAction.GET_EXISTING).avgLatency; + data.get_existing_p50_latency = calculatedResults.get(ChosenAction.GET_EXISTING).p50Latency; + data.get_existing_p90_latency = calculatedResults.get(ChosenAction.GET_EXISTING).p90Latency; + data.get_existing_p99_latency = calculatedResults.get(ChosenAction.GET_EXISTING).p99Latency; + data.get_existing_std_dev = calculatedResults.get(ChosenAction.GET_EXISTING).stdDeviation; + + data.get_non_existing_average_latency = + calculatedResults.get(ChosenAction.GET_NON_EXISTING).avgLatency; + data.get_non_existing_p50_latency = + calculatedResults.get(ChosenAction.GET_NON_EXISTING).p50Latency; + data.get_non_existing_p90_latency = + calculatedResults.get(ChosenAction.GET_NON_EXISTING).p90Latency; + data.get_non_existing_p99_latency = + calculatedResults.get(ChosenAction.GET_NON_EXISTING).p99Latency; + data.get_non_existing_std_dev = + calculatedResults.get(ChosenAction.GET_NON_EXISTING).stdDeviation; + + data.set_average_latency = calculatedResults.get(ChosenAction.SET).avgLatency; + data.set_p50_latency = calculatedResults.get(ChosenAction.SET).p50Latency; + data.set_p90_latency = calculatedResults.get(ChosenAction.SET).p90Latency; + data.set_p99_latency = calculatedResults.get(ChosenAction.SET).p99Latency; + data.set_std_dev = calculatedResults.get(ChosenAction.SET).stdDeviation; + + recordings.add(data); + + Files.write(path, gson.toJson(recordings).getBytes()); + } catch (IOException e) { + System.out.printf( + "Failed to write measurement results into a file '%s': %s%n", + resultsFile, e.getMessage()); + e.printStackTrace(); + } + } + + @Getter + public static class Measurements { + private String client; + private int clientCount; + private int data_size; + private double get_existing_average_latency; + private double get_existing_p50_latency; + private double get_existing_p90_latency; + private double get_existing_p99_latency; + private double get_existing_std_dev; + private double get_non_existing_average_latency; + private double get_non_existing_p50_latency; + private double get_non_existing_p90_latency; + private double get_non_existing_p99_latency; + private double get_non_existing_std_dev; + private boolean is_cluster; + private int num_of_tasks; + private double set_average_latency; + private double set_p50_latency; + private double set_p90_latency; + private double set_p99_latency; + private double set_std_dev; + private double tps; + } +} diff --git a/java/benchmarks/src/test/java/javababushka/benchmarks/jedis/JedisClientIT.java b/java/benchmarks/src/test/java/javababushka/benchmarks/jedis/JedisClientIT.java index ec40c00bb0..37eff60101 100644 --- a/java/benchmarks/src/test/java/javababushka/benchmarks/jedis/JedisClientIT.java +++ b/java/benchmarks/src/test/java/javababushka/benchmarks/jedis/JedisClientIT.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import javababushka.benchmarks.utils.Benchmarking; @@ -55,7 +56,16 @@ public void testResourceSetGet() { ChosenAction.GET_NON_EXISTING, () -> jedisClient.get(Benchmarking.generateKeyGet())); actions.put(ChosenAction.SET, () -> jedisClient.set(Benchmarking.generateKeySet(), value)); - Benchmarking.printResults( - Benchmarking.calculateResults(Benchmarking.getLatencies(iterations, actions))); + Map> latencies = + Map.of( + ChosenAction.GET_EXISTING, new ArrayList<>(), + ChosenAction.GET_NON_EXISTING, new ArrayList<>(), + ChosenAction.SET, new ArrayList<>()); + for (int i = 0; i < iterations; i++) { + var latency = Benchmarking.getLatency(actions); + latencies.get(latency.getKey()).add(latency.getValue()); + } + + Benchmarking.printResults(Benchmarking.calculateResults(latencies)); } }