improve tuple performance tester for more types and add serialization check in TupleTest
This commit is contained in:
parent
78ff3d92c1
commit
e6ce0ebd27
|
@ -13,30 +13,40 @@ import com.apple.foundationdb.tuple.Versionstamp;
|
|||
|
||||
public class TuplePerformanceTest {
|
||||
|
||||
private enum GeneratedTypes {
|
||||
ALL,
|
||||
LONG,
|
||||
FLOATING_POINT
|
||||
}
|
||||
|
||||
private final Random r;
|
||||
private final int ignoreIterations;
|
||||
private final int iterations;
|
||||
private final GeneratedTypes generatedTypes;
|
||||
|
||||
public TuplePerformanceTest(Random r, int ignoreIterations, int iterations) {
|
||||
public TuplePerformanceTest(Random r, int ignoreIterations, int iterations, GeneratedTypes generatedTypes) {
|
||||
this.r = r;
|
||||
this.ignoreIterations = ignoreIterations;
|
||||
this.iterations = iterations;
|
||||
this.generatedTypes = generatedTypes;
|
||||
}
|
||||
|
||||
public Tuple createTuple(int length) {
|
||||
public Tuple createMultiTypeTuple(int length) {
|
||||
List<Object> values = new ArrayList<>(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
for(int i = 0; i < length; i++) {
|
||||
double choice = r.nextDouble();
|
||||
if (choice < 0.1) {
|
||||
if(choice < 0.1) {
|
||||
values.add(null);
|
||||
} else if (choice < 0.2) {
|
||||
}
|
||||
else if(choice < 0.2) {
|
||||
byte[] bytes = new byte[r.nextInt(20)];
|
||||
r.nextBytes(bytes);
|
||||
values.add(bytes);
|
||||
} else if (choice < 0.3) {
|
||||
}
|
||||
else if(choice < 0.3) {
|
||||
char[] chars = new char[r.nextInt(20)];
|
||||
for (int j = 0; j < chars.length; j++) {
|
||||
chars[j] = (char)('a' + r.nextInt(26));
|
||||
chars[j] = (char) ('a' + r.nextInt(26));
|
||||
}
|
||||
values.add(new String(chars));
|
||||
}
|
||||
|
@ -67,7 +77,55 @@ public class TuplePerformanceTest {
|
|||
values.add(nested);
|
||||
}
|
||||
}
|
||||
return Tuple.from(values);
|
||||
return Tuple.fromItems(values);
|
||||
}
|
||||
|
||||
public Tuple createLongsTuple(int length) {
|
||||
List<Object> values = new ArrayList<>(length);
|
||||
for(int i = 0; i < length; i++) {
|
||||
int byteLength = r.nextInt(Long.BYTES + 1);
|
||||
long val = 0L;
|
||||
for(int x = 0; x < byteLength; x++) {
|
||||
int nextBytes = r.nextInt(256);
|
||||
val = (val << 8) + nextBytes;
|
||||
}
|
||||
values.add(val);
|
||||
}
|
||||
return Tuple.fromItems(values);
|
||||
}
|
||||
|
||||
public Tuple createFloatingPointTuple(int length) {
|
||||
List<Object> values = new ArrayList<>(length);
|
||||
for(int i = 0; i < length; i++) {
|
||||
double choice = r.nextDouble();
|
||||
if(choice < 0.40) {
|
||||
values.add(r.nextFloat());
|
||||
}
|
||||
else if(choice < 0.80) {
|
||||
values.add(r.nextDouble());
|
||||
}
|
||||
// These last two are more likely to produce NaN values
|
||||
else if(choice < 0.90) {
|
||||
values.add(Float.intBitsToFloat(r.nextInt()));
|
||||
}
|
||||
else {
|
||||
values.add(Double.longBitsToDouble(r.nextLong()));
|
||||
}
|
||||
}
|
||||
return Tuple.fromItems(values);
|
||||
}
|
||||
|
||||
public Tuple createTuple(int length) {
|
||||
switch (generatedTypes) {
|
||||
case ALL:
|
||||
return createMultiTypeTuple(length);
|
||||
case LONG:
|
||||
return createLongsTuple(length);
|
||||
case FLOATING_POINT:
|
||||
return createFloatingPointTuple(length);
|
||||
default:
|
||||
throw new IllegalStateException("unknown generated types " + generatedTypes);
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
@ -169,7 +227,7 @@ public class TuplePerformanceTest {
|
|||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
TuplePerformanceTest tester = new TuplePerformanceTest(new Random(), 100_000, 10_000_000);
|
||||
TuplePerformanceTest tester = new TuplePerformanceTest(new Random(), 100_000, 10_000_000, GeneratedTypes.ALL);
|
||||
tester.run();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,24 +20,116 @@
|
|||
|
||||
package com.apple.foundationdb.test;
|
||||
|
||||
import com.apple.foundationdb.Database;
|
||||
import com.apple.foundationdb.FDB;
|
||||
import com.apple.foundationdb.TransactionContext;
|
||||
import com.apple.foundationdb.tuple.ByteArrayUtil;
|
||||
import com.apple.foundationdb.tuple.Tuple;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class TupleTest {
|
||||
private static final byte FF = (byte)0xff;
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
final int reps = 1000;
|
||||
try {
|
||||
FDB fdb = FDB.selectAPIVersion(610);
|
||||
// FDB fdb = FDB.selectAPIVersion(610);
|
||||
serializedForms();
|
||||
/*
|
||||
try(Database db = fdb.open()) {
|
||||
runTests(reps, db);
|
||||
}
|
||||
*/
|
||||
} catch(Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static class TupleSerialization {
|
||||
private final Tuple tuple;
|
||||
private final byte[] serialization;
|
||||
|
||||
TupleSerialization(Tuple tuple, byte[] serialization) {
|
||||
this.tuple = tuple;
|
||||
this.serialization = serialization;
|
||||
}
|
||||
|
||||
static void addAll(List<TupleSerialization> list, Object... args) {
|
||||
for(int i = 0; i < args.length; i += 2) {
|
||||
TupleSerialization serialization = new TupleSerialization((Tuple)args[i], (byte[])args[i + 1]);
|
||||
list.add(serialization);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void serializedForms() {
|
||||
List<TupleSerialization> serializations = new ArrayList<>();
|
||||
TupleSerialization.addAll(serializations,
|
||||
Tuple.from(0L), new byte[]{0x14},
|
||||
Tuple.from(BigInteger.ZERO), new byte[]{0x14},
|
||||
Tuple.from(1L), new byte[]{0x15, 0x01},
|
||||
Tuple.from(BigInteger.ONE), new byte[]{0x15, 0x01},
|
||||
Tuple.from(-1L), new byte[]{0x13, FF - 1},
|
||||
Tuple.from(BigInteger.ONE.negate()), new byte[]{0x13, FF - 1},
|
||||
Tuple.from(255L), new byte[]{0x15, FF},
|
||||
Tuple.from(BigInteger.valueOf(255)), new byte[]{0x15, FF},
|
||||
Tuple.from(-255L), new byte[]{0x13, 0x00},
|
||||
Tuple.from(BigInteger.valueOf(-255)), new byte[]{0x13, 0x00},
|
||||
Tuple.from(256L), new byte[]{0x16, 0x01, 0x00},
|
||||
Tuple.from(BigInteger.valueOf(256)), new byte[]{0x16, 0x01, 0x00},
|
||||
Tuple.from(-256L), new byte[]{0x12, FF - 1, FF},
|
||||
Tuple.from(BigInteger.valueOf(-256)), new byte[]{0x12, FF - 1, FF},
|
||||
Tuple.from(65536), new byte[]{0x17, 0x01, 0x00, 0x00},
|
||||
Tuple.from(-65536), new byte[]{0x11, FF - 1, FF, FF},
|
||||
Tuple.from(Long.MAX_VALUE), new byte[]{0x1C, 0x7f, FF, FF, FF, FF, FF, FF, FF},
|
||||
Tuple.from(BigInteger.valueOf(Long.MAX_VALUE)), new byte[]{0x1C, 0x7f, FF, FF, FF, FF, FF, FF, FF},
|
||||
Tuple.from(BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE)), new byte[]{0x1C, (byte)0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
Tuple.from(BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE)), new byte[]{0x1C, FF, FF, FF, FF, FF, FF, FF, FF},
|
||||
Tuple.from(BigInteger.ONE.shiftLeft(64)), new byte[]{0x1D, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
Tuple.from(-((1L << 32) - 1)), new byte[]{0x10, 0x00, 0x00, 0x00, 0x00},
|
||||
Tuple.from(BigInteger.ONE.shiftLeft(32).subtract(BigInteger.ONE).negate()), new byte[]{0x10, 0x00, 0x00, 0x00, 0x00},
|
||||
Tuple.from(Long.MIN_VALUE + 2), new byte[]{0x0C, (byte)0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
|
||||
Tuple.from(Long.MIN_VALUE + 1), new byte[]{0x0C, (byte)0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
Tuple.from(BigInteger.valueOf(Long.MIN_VALUE).add(BigInteger.ONE)), new byte[]{0x0C, (byte)0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
Tuple.from(Long.MIN_VALUE), new byte[]{0x0C, 0x7f, FF, FF, FF, FF, FF, FF, FF},
|
||||
Tuple.from(BigInteger.valueOf(Long.MIN_VALUE)), new byte[]{0x0C, 0x7f, FF, FF, FF, FF, FF, FF, FF},
|
||||
Tuple.from(BigInteger.valueOf(Long.MIN_VALUE).subtract(BigInteger.ONE)), new byte[]{0x0C, 0x7f, FF, FF, FF, FF, FF, FF, FF - 1},
|
||||
Tuple.from(BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE).negate()), new byte[]{0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
Tuple.from(3.14f), new byte[]{0x20, (byte)0xc0, 0x48, (byte)0xf5, (byte)0xc3},
|
||||
Tuple.from(-3.14f), new byte[]{0x20, (byte)0x3f, (byte)0xb7, (byte)0x0a, (byte)0x3c},
|
||||
Tuple.from(3.14), new byte[]{0x21, (byte)0xc0, (byte)0x09, (byte)0x1e, (byte)0xb8, (byte)0x51, (byte)0xeb, (byte)0x85, (byte)0x1f},
|
||||
Tuple.from(-3.14), new byte[]{0x21, (byte)0x3f, (byte)0xf6, (byte)0xe1, (byte)0x47, (byte)0xae, (byte)0x14, (byte)0x7a, (byte)0xe0},
|
||||
Tuple.from(0.0f), new byte[]{0x20, (byte)0x80, 0x00, 0x00, 0x00},
|
||||
Tuple.from(-0.0f), new byte[]{0x20, 0x7f, FF, FF, FF},
|
||||
Tuple.from(0.0), new byte[]{0x21, (byte)0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
Tuple.from(-0.0), new byte[]{0x21, 0x7f, FF, FF, FF, FF, FF, FF, FF},
|
||||
Tuple.from(Float.POSITIVE_INFINITY), new byte[]{0x20, FF, (byte)0x80, 0x00, 0x00},
|
||||
Tuple.from(Float.NEGATIVE_INFINITY), new byte[]{0x20, 0x00, 0x7f, FF, FF},
|
||||
Tuple.from(Double.POSITIVE_INFINITY), new byte[]{0x21, FF, (byte)0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
Tuple.from(Double.NEGATIVE_INFINITY), new byte[]{0x21, 0x00, 0x0f, FF, FF, FF, FF, FF, FF},
|
||||
Tuple.from(Float.intBitsToFloat(Integer.MAX_VALUE)), new byte[]{0x20, FF, FF, FF, FF},
|
||||
Tuple.from(Double.longBitsToDouble(Long.MAX_VALUE)), new byte[]{0x21, FF, FF, FF, FF, FF, FF, FF, FF},
|
||||
Tuple.from(Float.intBitsToFloat(~0)), new byte[]{0x20, 0x00, 0x00, 0x00, 0x00},
|
||||
Tuple.from(Double.longBitsToDouble(~0L)), new byte[]{0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||
);
|
||||
|
||||
for(TupleSerialization serialization : serializations) {
|
||||
System.out.println("Packing " + serialization.tuple + " (expecting: " + ByteArrayUtil.printable(serialization.serialization) + ")");
|
||||
if(!Arrays.equals(serialization.tuple.pack(), serialization.serialization)) {
|
||||
throw new RuntimeException("Tuple " + serialization.tuple + " has serialization " + ByteArrayUtil.printable(serialization.tuple.pack()) +
|
||||
" which does not match expected serialization " + ByteArrayUtil.printable(serialization.serialization));
|
||||
}
|
||||
if(!Objects.equals(serialization.tuple, Tuple.fromBytes(serialization.serialization))) {
|
||||
throw new RuntimeException("Tuple " + serialization.tuple + " does not match deserialization " + Tuple.fromBytes(serialization.serialization) +
|
||||
" which comes from serialization " + ByteArrayUtil.printable(serialization.serialization));
|
||||
}
|
||||
}
|
||||
System.out.println("All tuples had matching serializations");
|
||||
}
|
||||
|
||||
private static void runTests(final int reps, TransactionContext db) {
|
||||
System.out.println("Running tests...");
|
||||
long start = System.currentTimeMillis();
|
||||
|
|
Loading…
Reference in New Issue