kopia lustrzana https://github.com/onthegomap/planetiler
123 wiersze
3.4 KiB
Java
123 wiersze
3.4 KiB
Java
package com.onthegomap.planetiler.collection;
|
|
|
|
import java.time.Duration;
|
|
import java.util.PriorityQueue;
|
|
import java.util.Random;
|
|
import java.util.function.IntFunction;
|
|
import java.util.stream.IntStream;
|
|
|
|
/**
|
|
* Performance tests for {@link LongMinHeap} implementations.
|
|
*
|
|
* Times how long it takes to merge N sorted lists of random elements.
|
|
*/
|
|
public class BenchmarkKWayMerge {
|
|
public static void main(String[] args) {
|
|
for (int i = 0; i < 4; i++) {
|
|
System.err.println();
|
|
testMinHeap("quaternary", n -> LongMinHeap.newArrayHeap(n, Integer::compare));
|
|
System.err.println(String.join("\t",
|
|
"priorityqueue",
|
|
Long.toString(testPriorityQueue(10).toMillis()),
|
|
Long.toString(testPriorityQueue(100).toMillis()),
|
|
Long.toString(testPriorityQueue(1_000).toMillis()),
|
|
Long.toString(testPriorityQueue(10_000).toMillis())));
|
|
}
|
|
}
|
|
|
|
private static void testMinHeap(String name, IntFunction<LongMinHeap> constructor) {
|
|
System.err.println(String.join("\t",
|
|
name,
|
|
Long.toString(testUpdates(10, constructor).toMillis()),
|
|
Long.toString(testUpdates(100, constructor).toMillis()),
|
|
Long.toString(testUpdates(1_000, constructor).toMillis()),
|
|
Long.toString(testUpdates(10_000, constructor).toMillis())));
|
|
}
|
|
|
|
private static final Random random = new Random();
|
|
|
|
private static long[][] getVals(int size) {
|
|
int num = 10_000_000;
|
|
return IntStream.range(0, size)
|
|
.mapToObj(i -> random
|
|
.longs(0, 1_000_000_000)
|
|
.limit(num / size)
|
|
.sorted()
|
|
.toArray()
|
|
).toArray(long[][]::new);
|
|
}
|
|
|
|
private static Duration testUpdates(int size, IntFunction<LongMinHeap> heapFn) {
|
|
int[] indexes = new int[size];
|
|
long[][] vals = getVals(size);
|
|
var heap = heapFn.apply(size);
|
|
for (int i = 0; i < size; i++) {
|
|
heap.push(i, vals[i][indexes[i]++]);
|
|
}
|
|
var start = System.nanoTime();
|
|
while (!heap.isEmpty()) {
|
|
int id = heap.peekId();
|
|
int index = indexes[id]++;
|
|
long[] valList = vals[id];
|
|
if (index < valList.length) {
|
|
heap.updateHead(valList[index]);
|
|
} else {
|
|
heap.poll();
|
|
}
|
|
}
|
|
return Duration.ofNanos(System.nanoTime() - start);
|
|
}
|
|
|
|
static class Item implements Comparable<Item> {
|
|
long value;
|
|
int id;
|
|
|
|
@Override
|
|
public int compareTo(Item o) {
|
|
return Long.compare(value, o.value);
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object o) {
|
|
if (this == o) {
|
|
return true;
|
|
}
|
|
if (o == null || getClass() != o.getClass()) {
|
|
return false;
|
|
}
|
|
|
|
Item item = (Item) o;
|
|
|
|
return value == item.value;
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return (int) (value ^ (value >>> 32));
|
|
}
|
|
}
|
|
|
|
private static Duration testPriorityQueue(int size) {
|
|
long[][] vals = getVals(size);
|
|
int[] indexes = new int[size];
|
|
PriorityQueue<Item> heap = new PriorityQueue<>();
|
|
for (int i = 0; i < size; i++) {
|
|
Item item = new Item();
|
|
item.id = i;
|
|
item.value = vals[i][indexes[i]++];
|
|
heap.offer(item);
|
|
}
|
|
var start = System.nanoTime();
|
|
while (!heap.isEmpty()) {
|
|
var item = heap.poll();
|
|
int index = indexes[item.id]++;
|
|
long[] valList = vals[item.id];
|
|
if (index < valList.length) {
|
|
item.value = valList[index];
|
|
heap.offer(item);
|
|
}
|
|
}
|
|
return Duration.ofNanos(System.nanoTime() - start);
|
|
}
|
|
}
|