Skip to content

Instantly share code, notes, and snippets.

@t3rmin4t0r
Created October 4, 2012 18:07
Show Gist options
  • Save t3rmin4t0r/3835342 to your computer and use it in GitHub Desktop.
Save t3rmin4t0r/3835342 to your computer and use it in GitHub Desktop.
Test MMAP buffers in Java
JAVA=java
JAVA_ARGS=-server -Xmx2048m
all:
javac *.java
rm result large.txt;
for size in 8 16 64 256 512 1024 1500 2000; do \
$(JAVA) $(JAVA_ARGS) TestBuffers mapped $$size | tee -a result; \
$(JAVA) $(JAVA_ARGS) TestBuffers direct $$size | tee -a result; \
$(JAVA) $(JAVA_ARGS) TestBuffers array $$size | tee -a result;\
done
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.util.*;
class TestBuffers
{
public static int CHUNK = 256;
public static void main(String[] args) throws Exception {
Random r = new Random();
ByteBuffer b = null;
byte[] wrapped = null;
int M = 1024*1024;
int size = 64*M;
if(args.length > 1)
{
if(args.length == 2)
{
size = Integer.parseInt(args[1])*M;
}
if(args[0].equals("direct"))
{
b = ByteBuffer.wrap(new byte[size]);
}
else if(args[0].equals("array"))
{
wrapped = new byte[size];
b = ByteBuffer.wrap(wrapped);
}
else
{
b = NewFileBuffer("large.txt", size);
}
}
IntBuffer ib = b.asIntBuffer();
ib.position(0);
while(ib.remaining() > 4) {
ib.put(0);
}
long startNanos, endNanos;
if(wrapped != null)
{
System.out.println("Starting to sort items (array)");
startNanos = System.nanoTime();
for(int i = 0; i < 1; i++) {
b.position(0);
quicksort(wrapped, 0, (b.limit()/CHUNK)-1);
}
endNanos = System.nanoTime();
System.out.println("array,"+size+"," + ((endNanos - startNanos) / (1000 * 1000.0))+"");
}
else
{
System.out.println("Starting to sort items ("+b.getClass()+")");
startNanos = System.nanoTime();
for(int i = 0; i < 1; i++) {
b.position(0);
quicksort(b, 0, (b.limit()/CHUNK)-1);
}
endNanos = System.nanoTime();
System.out.println(b.getClass()+","+size+"," + ((endNanos - startNanos) / (1000 * 1000.0))+"");
}
}
private static ByteBuffer NewFileBuffer(String filename, int size) throws Exception {
RandomAccessFile file = new RandomAccessFile(filename, "rw");
FileChannel c = file.getChannel();
file.setLength(size);
ByteBuffer buffer = c.map(FileChannel.MapMode.READ_WRITE, 0, file.length());
return buffer;
}
private static int compare(byte[] a, byte[] b) {
return a[0] - b[0];
}
private static byte[] get(ByteBuffer numbers, int pos, byte[] key) {
numbers.position(CHUNK*pos);
numbers.get(key, 0, CHUNK);
return key;
}
private static byte[] put(ByteBuffer numbers, int pos, byte[] key) {
numbers.position(CHUNK*pos);
numbers.put(key, 0, CHUNK);
return key;
}
private static void quicksort(ByteBuffer numbers, int low, int high) {
int i = low, j = high;
// Get the pivot element from the middle of the list
byte[] pivot = new byte[CHUNK];
byte[] current = new byte[CHUNK];
// Divide into two lists
while (i <= j) {
// If the current value from the left list is smaller then the pivot
// element then get the next element from the left list
while (compare(get(numbers,i, current), pivot) < 0) {
i++;
}
// If the current value from the right list is larger then the pivot
// element then get the next element from the right list
while (compare(get(numbers,j, current), pivot) > 0) {
j--;
}
// If we have found a values in the left list which is larger then
// the pivot element and if we have found a value in the right list
// which is smaller then the pivot element then we exchange the
// values.
// As we are done we can increase i and j
if (i <= j) {
exchange(numbers, i, j);
i++;
j--;
}
}
// Recursion
if (low < j)
quicksort(numbers, low, j);
if (i < high)
quicksort(numbers, i, high);
}
private static void exchange(ByteBuffer numbers, int i, int j) {
byte[] tj = new byte[CHUNK];
byte[] ti = new byte[CHUNK];
get(numbers, i, ti);
get(numbers, j, tj);
put(numbers, i, tj);
put(numbers, j, ti);
}
private static byte[] get(byte[] numbers, int pos, byte[] key) {
System.arraycopy(numbers, pos, key, 0, CHUNK);
return key;
}
private static byte[] put(byte[] numbers, int pos, byte[] key) {
System.arraycopy(key, 0, numbers, pos, CHUNK );
return key;
}
private static void quicksort(byte[] numbers, int low, int high) {
int i = low, j = high;
// Get the pivot element from the middle of the list
byte[] pivot = new byte[CHUNK];
byte[] current = new byte[CHUNK];
// Divide into two lists
while (i <= j) {
// If the current value from the left list is smaller then the pivot
// element then get the next element from the left list
while (compare(get(numbers,i, current), pivot) < 0) {
i++;
}
// If the current value from the right list is larger then the pivot
// element then get the next element from the right list
while (compare(get(numbers,j, current), pivot) > 0) {
j--;
}
// If we have found a values in the left list which is larger then
// the pivot element and if we have found a value in the right list
// which is smaller then the pivot element then we exchange the
// values.
// As we are done we can increase i and j
if (i <= j) {
exchange(numbers, i, j);
i++;
j--;
}
}
// Recursion
if (low < j)
quicksort(numbers, low, j);
if (i < high)
quicksort(numbers, i, high);
}
private static void exchange(byte[] numbers, int i, int j) {
byte[] tj = new byte[CHUNK];
byte[] ti = new byte[CHUNK];
get(numbers, i, ti);
get(numbers, j, tj);
put(numbers, i, tj);
put(numbers, j, ti);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment