strangedb/src/test/java/it/cavallium/strangedb/tests/Performance.java

411 lines
16 KiB
Java
Raw Normal View History

2019-03-07 11:41:45 +01:00
package it.cavallium.strangedb.tests;
2019-03-02 17:47:24 +01:00
2019-03-07 11:41:45 +01:00
import it.cavallium.strangedb.functionalinterfaces.RunnableWithIO;
2019-03-07 16:20:34 +01:00
import it.cavallium.strangedb.java.annotations.*;
import it.cavallium.strangedb.java.database.DatabaseJava;
2019-03-07 19:02:10 +01:00
import it.cavallium.strangedb.java.objects.lists.EnhancedObjectStrangeDbList;
2019-04-20 03:46:59 +02:00
import it.cavallium.strangedb.java.objects.lists.ListQuery;
2019-03-07 19:02:10 +01:00
import it.cavallium.strangedb.java.objects.lists.ObjectStrangeDbList;
2019-04-20 03:46:59 +02:00
import it.cavallium.strangedb.java.objects.lists.ValuePointer;
import it.cavallium.strangedb.java.objects.lists.operations.ContainsIgnoreCase;
2019-04-24 01:10:57 +02:00
import it.cavallium.strangedb.tests.performance.PerformanceListQuery;
import it.cavallium.strangedb.tests.performance.PerformanceTest;
2019-04-20 03:46:59 +02:00
import it.cavallium.strangedb.tests.query.*;
2019-03-02 17:47:24 +01:00
import it.unimi.dsi.fastutil.longs.LongArrayList;
2019-03-07 16:20:34 +01:00
import it.cavallium.strangedb.java.objects.EnhancedObject;
import it.cavallium.strangedb.java.database.IDatabaseTools;
2019-03-07 11:41:45 +01:00
import it.cavallium.strangedb.VariableWrapper;
2019-03-02 17:47:24 +01:00
import java.io.IOException;
2019-04-20 03:46:59 +02:00
import java.nio.charset.StandardCharsets;
2019-03-02 17:47:24 +01:00
import java.nio.file.Files;
import java.nio.file.Path;
2019-03-06 21:21:28 +01:00
import java.nio.file.Paths;
2019-03-02 17:47:24 +01:00
import java.util.ArrayList;
2019-04-20 03:46:59 +02:00
import java.util.List;
import java.util.Random;
2019-03-02 17:47:24 +01:00
public class Performance {
2019-04-20 22:19:07 +02:00
private static int DIVISOR;
2019-03-02 17:47:24 +01:00
private static Path rootDirectory;
private static Path dbDataFile;
private static Path dbReferencesFile;
2019-04-24 01:10:57 +02:00
public static DatabaseJava db;
2019-04-20 03:46:59 +02:00
private static boolean tempDirectory;
2019-04-20 22:19:07 +02:00
private static final int BASE_WIDTH = 35;
private static final int SPACE_WIDTH = BASE_WIDTH + 35;
private static String spaces = "";
private static String bars = "";
private static boolean doFillTests;
private static boolean doLoadTests;
private static boolean doQueryTests;
private static boolean doInstantiationTests;
static {
for (int i = 0; i < SPACE_WIDTH; i++) {
spaces += " ";
bars += "-";
}
}
2019-03-02 17:47:24 +01:00
/**
*
* @param args args[0] = true for fast tests
* @throws IOException
* @throws InterruptedException
*/
public static void main(String[] args) throws IOException, InterruptedException {
2019-04-20 22:19:07 +02:00
DIVISOR = args.length > 0 ? Integer.parseInt(args[0]) : 1;
2019-03-06 21:21:28 +01:00
if (args.length >= 2) {
2019-04-20 22:19:07 +02:00
doQueryTests =
args[1].contains("query");
doFillTests =
args[1].contains("fill");
doLoadTests =
args[1].contains("load");
doInstantiationTests =
args[1].contains("new");
if (args[1].contains("all")) {
doQueryTests = true;
doFillTests = true;
doLoadTests = true;
doInstantiationTests = true;
}
}
if (args.length >= 3) {
rootDirectory = Paths.get(args[2]);
if (Files.notExists(rootDirectory)) {
2019-03-06 21:21:28 +01:00
Files.createDirectory(rootDirectory);
}
2019-04-20 03:46:59 +02:00
tempDirectory = false;
2019-03-06 21:21:28 +01:00
} else {
rootDirectory = Files.createTempDirectory("performance-tests");
2019-04-20 03:46:59 +02:00
tempDirectory = true;
2019-03-06 21:21:28 +01:00
}
2019-03-02 17:47:24 +01:00
generateDb();
System.out.println("Performance test started.");
2019-04-20 22:19:07 +02:00
System.out.println(bars + "---------------+-----------------------------------------------------------------");
System.out.println("Test name" + spaces.substring(0, spaces.length() - 5) + "Total Time | Time at 1 Time at 10 Time at 100 Time at 1K Time at 10K");
System.out.println(bars + "---------------+-----------------------------------------------------------------");
if (doInstantiationTests) {
2019-04-24 01:10:57 +02:00
testS("DatabaseCore creation", 300,PerformanceTest.createTest(Performance::deleteDb, Performance::generateDb, () -> {}));
testS("DatabaseCore root creation", 300, PerformanceTest.createTest(Performance::regenDb, () -> db.loadRoot(PreloadedListContainer::new), () -> {}));
2019-04-20 22:19:07 +02:00
}
2019-03-02 17:47:24 +01:00
final VariableWrapper<PreloadedListContainer> preloadedListContainer = new VariableWrapper<>(null);
final VariableWrapper<SimpleEnhancedObject> simpleEnhancedObjectContainer = new VariableWrapper<>(null);
2019-04-20 22:19:07 +02:00
if (doInstantiationTests) {
2019-04-24 01:10:57 +02:00
testS("ObjectStrangeDbList<Int> creation", 1000, PerformanceTest.createTest(() -> {
2019-04-20 03:46:59 +02:00
regenDb();
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
2019-04-24 01:10:57 +02:00
}, () -> preloadedListContainer.var.list = new ObjectStrangeDbList<>(db), () -> {}));
2019-04-20 22:19:07 +02:00
}
if (doFillTests) {
2019-04-24 01:10:57 +02:00
testS("ObjectStrangeDbList<Int>: Filling with 1000 items", 100, PerformanceTest.createTest(() -> {
2019-04-20 22:19:07 +02:00
regenDb();
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
preloadedListContainer.var.list = new ObjectStrangeDbList<>(db);
}, () -> {
for (int i = 0; i < 1000; i++) {
preloadedListContainer.var.list.add(1000);
2019-04-20 03:46:59 +02:00
}
2019-04-24 01:10:57 +02:00
}, () -> {}));
testS("ObjectStrangeDbList<EnhancedObject>: Filling with 1000 items", 100, PerformanceTest.createTest(() -> {
2019-04-20 22:19:07 +02:00
regenDb();
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
preloadedListContainer.var.listOfEnhancedObj = new EnhancedObjectStrangeDbList<>(db, SimpleEnhancedObject.class);
simpleEnhancedObjectContainer.var = new SimpleEnhancedObject(db);
simpleEnhancedObjectContainer.var.integerNumber = 10;
simpleEnhancedObjectContainer.var.longNumber = 10L;
simpleEnhancedObjectContainer.var.object = new ArrayList<>();
simpleEnhancedObjectContainer.var.object.add("XHIghicuiHUCB UIVY");
simpleEnhancedObjectContainer.var.object.add("ioZ>UIHZXGHXYGY");
simpleEnhancedObjectContainer.var.object.add("XJIOUIhcgGuigscwvyv");
2019-04-20 03:46:59 +02:00
}, () -> {
2019-04-20 22:19:07 +02:00
for (int i = 0; i < 1000; i++) {
preloadedListContainer.var.listOfEnhancedObj.add(simpleEnhancedObjectContainer.var);
}
2019-04-24 01:10:57 +02:00
}, () -> {}));
testS("ObjectStrangeDbList<Int>: Filling with 10000 items", 10, PerformanceTest.createTest(() -> {
2019-04-20 22:19:07 +02:00
regenDb();
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
preloadedListContainer.var.list = new ObjectStrangeDbList<>(db);
}, () -> {
for (int i = 0; i < 10000; i++) {
preloadedListContainer.var.list.add(1000);
}
2019-04-24 01:10:57 +02:00
}, () -> {}));
testS("ObjectStrangeDbList<Int>: Filling with 100000 items", 1, PerformanceTest.createTest(() -> {
2019-04-20 22:19:07 +02:00
regenDb();
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
preloadedListContainer.var.list = new ObjectStrangeDbList<>(db);
}, () -> {
for (int i = 0; i < 100000; i++) {
preloadedListContainer.var.list.add(1000);
}
2019-04-24 01:10:57 +02:00
}, () -> {}));
2019-04-20 03:46:59 +02:00
}
2019-04-20 22:19:07 +02:00
if (doLoadTests) {
2019-04-24 01:10:57 +02:00
testS("ObjectStrangeDbList<Int>: Loading 1000 items", 100, PerformanceTest.createTest(() -> {
2019-04-20 22:19:07 +02:00
regenDb();
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
preloadedListContainer.var.list = new ObjectStrangeDbList<>(db);
for (int i = 0; i < 1000; i++) {
preloadedListContainer.var.list.add(1000);
}
}, () -> {
preloadedListContainer.var.list.forEachParallelUnsorted((i) -> {});
2019-04-24 01:10:57 +02:00
}, () -> {}));
testS("ObjectStrangeDbList<EnhancedObject>: Loading with 1000 items", 100, PerformanceTest.createTest(() -> {
2019-04-20 22:19:07 +02:00
regenDb();
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
preloadedListContainer.var.listOfEnhancedObj = new EnhancedObjectStrangeDbList<>(db, SimpleEnhancedObject.class);
simpleEnhancedObjectContainer.var = new SimpleEnhancedObject(db);
simpleEnhancedObjectContainer.var.integerNumber = 10;
simpleEnhancedObjectContainer.var.longNumber = 10L;
simpleEnhancedObjectContainer.var.object = new ArrayList<>();
simpleEnhancedObjectContainer.var.object.add("XHIghicuiHUCB UIVY");
simpleEnhancedObjectContainer.var.object.add("ioZ>UIHZXGHXYGY");
simpleEnhancedObjectContainer.var.object.add("XJIOUIhcgGuigscwvyv");
for (int i = 0; i < 1000; i++) {
preloadedListContainer.var.listOfEnhancedObj.add(simpleEnhancedObjectContainer.var);
}
}, () -> {
preloadedListContainer.var.listOfEnhancedObj.forEachParallelUnsorted((i) -> {});
2019-04-24 01:10:57 +02:00
}, () -> {}));
testS("ObjectStrangeDbList<Int>: Loading 10000 items", 10, PerformanceTest.createTest(() -> {
2019-04-20 22:19:07 +02:00
regenDb();
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
preloadedListContainer.var.list = new ObjectStrangeDbList<>(db);
for (int i = 0; i < 10000; i++) {
preloadedListContainer.var.list.add(1000);
}
}, () -> {
preloadedListContainer.var.list.forEachParallelUnsorted((i) -> {});
2019-04-24 01:10:57 +02:00
}, () -> {}));
testS("ObjectStrangeDbList<Int>: getLast() with 1000 items", 100, PerformanceTest.createTest(() -> {
2019-04-20 22:19:07 +02:00
regenDb();
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
preloadedListContainer.var.list = new ObjectStrangeDbList<>(db);
for (int i = 0; i < 1000; i++) {
preloadedListContainer.var.list.add(1000);
}
}, () -> {
preloadedListContainer.var.list.getLast();
2019-04-24 01:10:57 +02:00
}, () -> {}));
testS("ObjectStrangeDbList<EnhancedObject>: getLast() with 1000 items", 100, PerformanceTest.createTest(() -> {
2019-04-20 22:19:07 +02:00
regenDb();
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
preloadedListContainer.var.listOfEnhancedObj = new EnhancedObjectStrangeDbList<>(db, SimpleEnhancedObject.class);
simpleEnhancedObjectContainer.var = new SimpleEnhancedObject(db);
simpleEnhancedObjectContainer.var.integerNumber = 10;
simpleEnhancedObjectContainer.var.longNumber = 10L;
simpleEnhancedObjectContainer.var.object = new ArrayList<>();
simpleEnhancedObjectContainer.var.object.add("XHIghicuiHUCB UIVY");
simpleEnhancedObjectContainer.var.object.add("ioZ>UIHZXGHXYGY");
simpleEnhancedObjectContainer.var.object.add("XJIOUIhcgGuigscwvyv");
for (int i = 0; i < 1000; i++) {
preloadedListContainer.var.listOfEnhancedObj.add(simpleEnhancedObjectContainer.var);
}
}, () -> {
preloadedListContainer.var.listOfEnhancedObj.getLast();
2019-04-24 01:10:57 +02:00
}, () -> {}));
testS("ObjectStrangeDbList<Int>: size() with 1000 items", 100, PerformanceTest.createTest(() -> {
2019-04-20 22:19:07 +02:00
regenDb();
preloadedListContainer.var = db.loadRoot(PreloadedListContainer::new);
preloadedListContainer.var.list = new ObjectStrangeDbList<>(db);
for (int i = 0; i < 1000; i++) {
preloadedListContainer.var.list.add(1000);
}
}, () -> {
preloadedListContainer.var.list.size();
2019-04-24 01:10:57 +02:00
}, () -> {}));
2019-04-20 22:19:07 +02:00
}
if (doQueryTests) {
for (int items = 1000; items <= 100000; items *= 10) {
2019-04-24 01:10:57 +02:00
testS("ListQuery: query with " + items + " items", 100 / (items / 1000), new PerformanceListQuery(items));
2019-04-20 22:19:07 +02:00
}
}
System.out.println(bars + "---------------+-----------------------------------------------------------------");
2019-03-02 17:47:24 +01:00
System.out.println("Performance test finished.");
deleteDb();
2019-04-20 03:46:59 +02:00
if (tempDirectory) {
Files.deleteIfExists(rootDirectory);
}
2019-03-02 17:47:24 +01:00
}
private static void NtestS(String description, int times, RunnableWithIO beforeAction, RunnableWithIO action, RunnableWithIO afterAction) throws IOException, InterruptedException {
}
2019-04-24 01:10:57 +02:00
private static void testS(String description, int times, PerformanceTest test) throws IOException, InterruptedException {
2019-04-20 22:19:07 +02:00
if (times >= 5 * DIVISOR) {
times /= 5 * DIVISOR;
} else if (times >= 2 * DIVISOR) {
times /= 2 * DIVISOR;
2019-03-02 17:47:24 +01:00
}
description = description + " time is";
2019-04-20 22:19:07 +02:00
int spacesCount = SPACE_WIDTH - description.length();
2019-03-02 17:47:24 +01:00
int cutAt = 0;
if (spacesCount < 0) {
2019-04-20 22:19:07 +02:00
spacesCount = SPACE_WIDTH - (description.length() - SPACE_WIDTH);
cutAt = SPACE_WIDTH;
2019-03-02 17:47:24 +01:00
}
StringBuilder spaces = new StringBuilder();
for (int i = 0; i < spacesCount; i++) {
spaces.append(' ');
}
2019-04-24 01:10:57 +02:00
double[] results = test(times, test);
2019-03-02 17:47:24 +01:00
if (cutAt > 0) {
System.out.println(description.substring(0, cutAt) + " |");
}
System.out.printf("%s:%s%s%s%n", description.substring(cutAt), spaces, format(results[0]) + " |", results.length > 1 ? (format(results[1]) + (results.length > 2 ? (format(results[2]) + (results.length > 3 ? (format(results[3]) + (results.length > 4 ? (format(results[4]) + (results.length > 5 ? format(results[5]) : "")) : "")) : "")) : "")) : "");
}
private static String format(double result) {
String spaces;
if (result < 10) {
spaces = " ";
} else if (result < 100) {
spaces = " ";
} else if (result < 1000) {
spaces = " ";
} else {
spaces = " ";
}
return spaces + String.format("%.2fms", result);
}
2019-04-24 01:10:57 +02:00
private static double[] test(int times, PerformanceTest test) throws IOException, InterruptedException {
2019-03-02 17:47:24 +01:00
LongArrayList results = new LongArrayList(times);
Thread.sleep(100);
System.gc();
Thread.sleep(100);
2019-04-24 01:10:57 +02:00
test.setup();
2019-03-02 17:47:24 +01:00
for (int i = 0; i < times; i++) {
2019-04-24 01:10:57 +02:00
test.perTestSetup();
2019-03-02 17:47:24 +01:00
long startTime = System.nanoTime();
2019-04-24 01:10:57 +02:00
test.test();
2019-03-02 17:47:24 +01:00
long elapsedTime = System.nanoTime() - startTime;
2019-04-24 01:10:57 +02:00
test.perTestEnd();
2019-03-02 17:47:24 +01:00
results.add(elapsedTime);
}
2019-04-24 01:10:57 +02:00
test.end();
2019-03-02 17:47:24 +01:00
double result1 = results.stream().limit(1).mapToLong(val -> val).average().orElse(0.0) / 1000000d;
double result10 = results.stream().limit(10).mapToLong(val -> val).average().orElse(0.0) / 1000000d;
double result100 = results.stream().limit(100).mapToLong(val -> val).average().orElse(0.0) / 1000000d;
double result1000 = results.stream().limit(1000).mapToLong(val -> val).average().orElse(0.0) / 1000000d;
double result10000 = results.stream().limit(10000).mapToLong(val -> val).average().orElse(0.0) / 1000000d;
double resultMax = results.stream().mapToLong(val -> val).average().orElse(0.0) / 1000000d;
if (times <= 1) {
return new double[]{resultMax};
} else if (times <= 10) {
return new double[]{resultMax, result1};
} else if (times <= 100) {
return new double[]{resultMax, result1, result10};
} else if (times <= 1000) {
return new double[]{resultMax, result1, result10, result100};
} else if (times <= 10000) {
return new double[]{resultMax, result1, result10, result100, result1000};
} else {
return new double[]{resultMax, result1, result10, result100, result1000, result10000};
}
}
public static void generateDb() throws IOException {
2019-04-17 18:19:01 +02:00
dbDataFile = rootDirectory.resolve("db_data.dat");
dbReferencesFile = rootDirectory.resolve("db_references.dat");
deleteDbFolders();
Files.createFile(dbDataFile);
Files.createFile(dbReferencesFile);
2019-04-22 12:18:54 +02:00
db = new DatabaseJava(dbDataFile, dbReferencesFile);
2019-04-20 03:46:59 +02:00
int i = 0;
2019-04-20 17:02:57 +02:00
db.registerClass(SimpleEnhancedObject.class, i++);
db.registerClass(PreloadedListContainer.class, i++);
db.registerClass(DynamicListContainer.class, i++);
db.registerClass(EMessage.class, i++);
db.registerClass(EMessageContent.class, i++);
db.registerClass(EMessageText.class, i++);
db.registerClass(EMessageOtherContent.class, i++);
db.registerClass(EFormattedText.class, i++);
2019-03-02 17:47:24 +01:00
}
public static void deleteDb() throws IOException {
db.close();
2019-04-17 18:19:01 +02:00
deleteDbFolders();
}
public static void deleteDbFolders() throws IOException {
2019-03-02 17:47:24 +01:00
Files.deleteIfExists(dbDataFile);
Files.deleteIfExists(dbReferencesFile);
}
public static void regenDb() throws IOException {
deleteDb();
generateDb();
}
public static class PreloadedListContainer extends EnhancedObject {
2019-03-07 11:41:45 +01:00
@DbField(id = 0, type = DbDataType.ENHANCED_OBJECT)
2019-03-07 19:02:10 +01:00
public ObjectStrangeDbList<Integer> list;
2019-03-02 17:47:24 +01:00
2019-03-07 11:41:45 +01:00
@DbField(id = 1, type = DbDataType.ENHANCED_OBJECT)
2019-03-07 19:02:10 +01:00
public EnhancedObjectStrangeDbList<SimpleEnhancedObject> listOfEnhancedObj;
2019-03-02 17:47:24 +01:00
2019-04-20 03:46:59 +02:00
@DbField(id = 2, type = DbDataType.ENHANCED_OBJECT)
public EnhancedObjectStrangeDbList<EMessage> listOfMessages;
2019-03-02 17:47:24 +01:00
public PreloadedListContainer() {
}
public PreloadedListContainer(IDatabaseTools databaseTools) throws IOException {
super(databaseTools);
}
}
public static class DynamicListContainer extends EnhancedObject {
public DynamicListContainer() {
}
public DynamicListContainer(IDatabaseTools databaseTools) throws IOException {
super(databaseTools);
}
2019-04-18 16:08:22 +02:00
@DbProperty(id = 0, type = DbDataType.ENHANCED_OBJECT)
@DbPropertyGetter()
2019-03-07 19:02:10 +01:00
public ObjectStrangeDbList<Integer> getList() {
2019-03-02 17:47:24 +01:00
return getProperty();
}
2019-04-18 16:08:22 +02:00
@DbProperty(id = 1, type = DbDataType.ENHANCED_OBJECT)
@DbPropertySetter()
2019-03-07 19:02:10 +01:00
public void setList(ObjectStrangeDbList<Integer> list) {
2019-03-02 17:47:24 +01:00
setProperty(list);
}
}
public static class SimpleEnhancedObject extends EnhancedObject {
public SimpleEnhancedObject() {
}
public SimpleEnhancedObject(IDatabaseTools databaseTools) throws IOException {
super(databaseTools);
}
2019-03-07 11:41:45 +01:00
@DbField(id = 0, type = DbDataType.OBJECT)
2019-03-02 17:47:24 +01:00
public ArrayList<String> object;
2019-03-07 11:41:45 +01:00
@DbPrimitiveField(id = 0, type = DbPrimitiveType.INTEGER)
2019-03-02 17:47:24 +01:00
public int integerNumber;
2019-03-07 11:41:45 +01:00
@DbPrimitiveField(id = 1, type = DbPrimitiveType.LONG)
2019-03-02 17:47:24 +01:00
public long longNumber;
}
}