Add a perf test for acquireUsingLocked.

This commit is contained in:
Peter Lawrey
2014-11-02 23:09:21 +00:00
parent 2e98febfeb
commit 245908baad
4 changed files with 94 additions and 22 deletions
@@ -115,7 +115,7 @@ public abstract class AbstractChronicleMapBuilder<K, V,
private int valueSize = 0;
private V sampleValue;
private int entrySize = 0;
private Alignment alignment;
private Alignment alignment = null;
private long entries = 1 << 20; // 1 million by default
private long lockTimeOut = 2000;
private TimeUnit lockTimeOutUnit = TimeUnit.MILLISECONDS;
@@ -138,10 +138,9 @@ public abstract class AbstractChronicleMapBuilder<K, V,
private StatelessBuilder statelessBuilder;
private File file;
AbstractChronicleMapBuilder(Class<K> keyClass, Class<V> valueClass, Alignment alignment) {
AbstractChronicleMapBuilder(Class<K> keyClass, Class<V> valueClass) {
keyBuilder = new SerializationBuilder<K>(keyClass, SerializationBuilder.Role.KEY);
valueBuilder = new SerializationBuilder<V>(valueClass, SerializationBuilder.Role.VALUE);
this.alignment = alignment;
}
protected static boolean offHeapReference(Class valueClass) {
@@ -318,7 +317,9 @@ public abstract class AbstractChronicleMapBuilder<K, V,
}
Alignment entryAndValueAlignment() {
return alignment;
if (alignment != null)
return alignment;
return offHeapReference(valueBuilder.eClass) ? Alignment.OF_4_BYTES : Alignment.NO_ALIGNMENT;
}
@Override
@@ -73,11 +73,7 @@ public final class ChronicleMapBuilder<K, V>
}
ChronicleMapBuilder(Class<K> keyClass, Class<V> valueClass) {
super(keyClass, valueClass, getAlignmentFor(valueClass));
}
private static <V> Alignment getAlignmentFor(Class<V> valueClass) {
return offHeapReference(valueClass) ? Alignment.OF_4_BYTES : Alignment.NO_ALIGNMENT;
super(keyClass, valueClass);
}
@Override
@@ -37,7 +37,7 @@ public final class OffHeapUpdatableChronicleMapBuilder<K, V>
}
OffHeapUpdatableChronicleMapBuilder(Class<K> keyClass, Class<V> valueClass) {
super(keyClass, valueClass, Alignment.OF_4_BYTES);
super(keyClass, valueClass);
prepareValueBytesOnAcquire(new ZeroOutValueBytes<K, V>(valueSize()));
}
@@ -74,7 +74,7 @@ public final class OffHeapUpdatableChronicleMapBuilder<K, V>
* alignment. I. e. if you set {@code entrySize(20)} and {@link Alignment#OF_8_BYTES}, actual
* entry size will be 24 (20 aligned to 8 bytes).
*
* <p>Default is {@link Alignment#NO_ALIGNMENT}.
* <p>Default is {@link Alignment#OF_4_BYTES} for Byteable values.
*
* @param alignment the new alignment of the maps constructed by this builder
* @return this {@code ChronicleMapBuilder} back
@@ -575,25 +575,28 @@ public class ChronicleMapTest {
throws IOException, ClassNotFoundException, IllegalAccessException,
InstantiationException, InterruptedException, ExecutionException {
// int runs = Integer.getInteger("runs", 10);
int procs = Runtime.getRuntime().availableProcessors();
int threads = procs * 2; // runs > 100 ? procs / 2 : procs;
ExecutorService es = Executors.newFixedThreadPool(procs);
for (int runs : new int[]{10, 50, 250, 500, 1000, 2500}) {
// JAVA 8 produces more garbage than previous versions for internal work.
// System.gc();
final long entries = runs * 1000 * 1000L;
OffHeapUpdatableChronicleMapBuilder<CharSequence, LongValue> builder = OffHeapUpdatableChronicleMapBuilder
.of(CharSequence.class, LongValue.class)
.entries(entries)
.entryAndValueAlignment(OF_8_BYTES)
.entrySize(24);
File tmpFile = File.createTempFile("testAcquirePerf", ".deleteme");
tmpFile.deleteOnExit();
final ChronicleMap<CharSequence, LongValue> map = builder.createWithFile(tmpFile);
int procs = Runtime.getRuntime().availableProcessors();
int threads = procs * 2; // runs > 100 ? procs / 2 : procs;
int count = runs > 500 ? runs > 1200 ? 1 : 3 : 5;
final int independence = 8; // Math.min(procs, runs > 500 ? 8 : 4);
int count = runs > 500 ? runs > 1200 ? 3 : 5 : 5;
final int independence = Math.min(procs, runs > 500 ? 8 : 4);
System.out.println("\nKey size: " + runs + " Million entries. " + builder);
for (int j = 0; j < count; j++) {
long start = System.currentTimeMillis();
ExecutorService es = Executors.newFixedThreadPool(procs);
List<Future> futures = new ArrayList<Future>();
for (int i = 0; i < threads; i++) {
final int t = i;
@@ -625,8 +628,6 @@ public class ChronicleMapTest {
for (Future future : futures) {
future.get();
}
es.shutdown();
es.awaitTermination(runs / 10 + 1, TimeUnit.MINUTES);
long time = System.currentTimeMillis() - start;
System.out.printf("Throughput %.1f M ops/sec%n", threads * entries / independence / 1000.0 / time);
}
@@ -635,21 +636,95 @@ public class ChronicleMapTest {
map.close();
file.delete();
}
es.shutdown();
es.awaitTermination(1, TimeUnit.MINUTES);
}
@Test
@Ignore
public void testAcquireLockedPerf()
throws IOException, ClassNotFoundException, IllegalAccessException,
InstantiationException, InterruptedException, ExecutionException {
// int runs = Integer.getInteger("runs", 10);
int procs = Runtime.getRuntime().availableProcessors();
int threads = procs * 2; // runs > 100 ? procs / 2 : procs;
ExecutorService es = Executors.newFixedThreadPool(procs);
for (int runs : new int[]{10, 50, 250, 500, 1000, 2500}) {
// JAVA 8 produces more garbage than previous versions for internal work.
// System.gc();
final long entries = runs * 1000 * 1000L;
OffHeapUpdatableChronicleMapBuilder<CharSequence, LongValue> builder = OffHeapUpdatableChronicleMapBuilder
.of(CharSequence.class, LongValue.class)
.entries(entries)
.entryAndValueAlignment(OF_8_BYTES)
.entrySize(24);
File tmpFile = File.createTempFile("testAcquirePerf", ".deleteme");
tmpFile.deleteOnExit();
final ChronicleMap<CharSequence, LongValue> map = builder.createWithFile(tmpFile);
int count = runs > 500 ? runs > 1200 ? 3 : 5 : 5;
final int independence = Math.min(procs, runs > 500 ? 8 : 4);
System.out.println("\nKey size: " + runs + " Million entries. " + builder);
for (int j = 0; j < count; j++) {
long start = System.currentTimeMillis();
List<Future> futures = new ArrayList<Future>();
for (int i = 0; i < threads; i++) {
final int t = i;
futures.add(es.submit(new Runnable() {
@Override
public void run() {
LongValue value = nativeLongValue();
StringBuilder sb = new StringBuilder();
long next = 50 * 1000 * 1000;
// use a factor to give up to 10 digit numbers.
int factor = Math.max(1, (int) ((10 * 1000 * 1000 * 1000L - 1) / entries));
for (long j = t % independence; j < entries + independence - 1; j += independence) {
sb.setLength(0);
sb.append("us:");
sb.append(j * factor);
long n;
try(WriteContext wc = map.acquireUsingLocked(sb, value)) {
n = value.addValue(1);
}
assert n > 0 && n < 1000 : "Counter corrupted " + n;
if (t == 0 && j >= next) {
long size = map.longSize();
if (size < 0) throw new AssertionError("size: " + size);
System.out.println(j + ", size: " + size);
next += 50 * 1000 * 1000;
}
}
}
}));
}
for (Future future : futures) {
future.get();
}
long time = System.currentTimeMillis() - start;
System.out.printf("Throughput %.1f M ops/sec%n", threads * entries / independence / 1000.0 / time);
}
printStatus();
File file = map.file();
map.close();
file.delete();
}
es.shutdown();
es.awaitTermination(1, TimeUnit.MINUTES);
}
@Test
@Ignore
public void testCHMAcquirePerf() throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, InterruptedException {
for (int runs : new int[]{10, 50, 250, 1000, 2500}) {
for (int runs : new int[]{10, 50, 250, 500, 1000, 2500}) {
System.out.println("Testing " + runs + " million entries");
final long entries = runs * 1000 * 1000L;
final ConcurrentMap<String, AtomicInteger> map = new ConcurrentHashMap<String, AtomicInteger>((int) (entries * 5 / 4), 1.0f, 1024);
int procs = Runtime.getRuntime().availableProcessors();
int threads = procs * 2;
int count = runs > 500 ? runs > 1200 ? 1 : 2 : 3;
int count = runs > 500 ? runs > 1200 ? 1 : 2 : 5;
final int independence = Math.min(procs, runs > 500 ? 8 : 4);
for (int j = 0; j < count; j++) {
final ConcurrentMap<String, AtomicInteger> map = new ConcurrentHashMap<String, AtomicInteger>((int) (entries * 5 / 4), 1.0f, 1024);
long start = System.currentTimeMillis();
ExecutorService es = Executors.newFixedThreadPool(procs);
for (int i = 0; i < threads; i++) {
@@ -668,7 +743,7 @@ public class ChronicleMapTest {
String key = sb.toString();
AtomicInteger count = map.get(key);
if (count == null) {
map.put(key, new AtomicInteger());
map.putIfAbsent(key, new AtomicInteger());
count = map.get(key);
}
count.getAndIncrement();