Created
October 4, 2012 18:07
-
-
Save t3rmin4t0r/3835342 to your computer and use it in GitHub Desktop.
Test MMAP buffers in Java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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