Skip to content

Instantly share code, notes, and snippets.

@dmikurube
Forked from frsyuki/DeserBenchmark.java
Last active May 20, 2021 09:25
Show Gist options
  • Save dmikurube/c48ac6432cb4c2151ff9c75cd253bcd5 to your computer and use it in GitHub Desktop.
Save dmikurube/c48ac6432cb4c2151ff9c75cd253bcd5 to your computer and use it in GitHub Desktop.
Split DeserBenchmark.java
import java.util.Random;
import sun.misc.Unsafe;
import sun.nio.ch.DirectBuffer;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class DeserBenchmark {
public static void main(String[] args) throws Exception {
if (args.length != 3) {
System.out.println("usage: <seed> <size> <loop>");
System.exit(1);
}
long seed = Long.parseLong(args[0]);
int size = Integer.parseInt(args[1]);
int loop = Integer.parseInt(args[2]);
new DeserBenchmark().run(seed, size, loop);
}
public void run(long seed, int size, int loop) {
if (seed == 0) {
seed = new Random().nextInt();
}
System.out.printf("seed: %d%n", seed);
System.out.printf("size: %d bytes%n", size);
System.out.printf("loop: %d times%n", loop);
byte[] bytes = new byte[size];
new Random(seed).nextBytes(bytes);
ByteBuffer heap = ByteBuffer.wrap(bytes);
ByteBuffer direct = ByteBuffer.allocateDirect(size);
direct.put(bytes);
measure("ByteBuffer heap", size, loop, new ByteBufferRunnable(heap));
measure("ByteBuffer direct", size, loop, new ByteBufferRunnable(direct));
measure("Unsafe heap", size, loop, new HeapUnsafeRunnable(bytes));
measure("Unsafe direct", size, loop, new DirectUnsafeRunnable(direct));
System.out.println("writing data to random.data file");
try {
new FileOutputStream(new File("random.data")).write(bytes);
} catch (IOException ex) {
ex.printStackTrace();
}
}
private void measure(String name, int size, int loop, Runnable runnable) {
// warm-up
for (int i=0; i < loop; i++) {
runnable.run();
}
long startTime = System.currentTimeMillis();
for (int i=0; i < loop; i++) {
runnable.run();
}
long time = System.currentTimeMillis() - startTime;
double mbs = size * (long) loop / ((double) time / 1000) / 1024 / 1024;
double msec = time / (double) loop;
System.out.printf("-- %s%n", name);
System.out.printf(" %.2f msec/loop%n", msec);
System.out.printf(" %.2f MB/s%n", mbs);
}
private static class ByteBufferRunnable implements Runnable {
private ByteBuffer src;
public int v32;
public long v64;
public ByteBufferRunnable(ByteBuffer src) {
this.src = src;
}
public void run() {
int last = src.limit() - 9;
for(int i=0; i < last; i++) {
byte b = src.get(i);
i++;
if(b < 0) {
v32 = src.getInt(i);
i += 4;
} else {
v64 = src.getLong(i);
i += 8;
}
}
}
}
private static class UnsafeRunnable implements Runnable {
private static final Unsafe unsafe;
public int v32;
public long v64;
static {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Object base;
private long address;
private int length;
public UnsafeRunnable(Object base, long address, int length) {
this.base = base;
this.length = length;
}
public void run() {
int last = length - 9;
for(int i=0; i < last; i++) {
byte b = unsafe.getByte(base, address + i);
i++;
if(b < 0) {
v32 = unsafe.getInt(base, address + i);
i += 4;
} else {
v64 = unsafe.getLong(base, address + i);
i += 8;
}
}
}
}
private static class HeapUnsafeRunnable extends UnsafeRunnable {
public HeapUnsafeRunnable(byte[] src) {
super(src, Unsafe.ARRAY_BYTE_BASE_OFFSET, src.length);
}
}
private static class DirectUnsafeRunnable extends UnsafeRunnable {
public DirectUnsafeRunnable(ByteBuffer src) {
super(src, ((DirectBuffer) src).address(), src.limit());
}
}
}
import java.util.Random;
import java.nio.ByteBuffer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class DeserBenchmarkByteBufferDirect {
public static void main(String[] args) throws Exception {
if (args.length != 3) {
System.out.println("usage: <seed> <size> <loop>");
System.exit(1);
}
long seed = Long.parseLong(args[0]);
int size = Integer.parseInt(args[1]);
int loop = Integer.parseInt(args[2]);
new DeserBenchmarkByteBufferDirect().run(seed, size, loop);
}
public void run(long seed, int size, int loop) {
if (seed == 0) {
seed = new Random().nextInt();
}
System.out.printf("seed: %d%n", seed);
System.out.printf("size: %d bytes%n", size);
System.out.printf("loop: %d times%n", loop);
byte[] bytes = new byte[size];
new Random(seed).nextBytes(bytes);
ByteBuffer direct = ByteBuffer.allocateDirect(size);
direct.put(bytes);
measure("ByteBuffer direct", size, loop, new ByteBufferRunnable(direct));
System.out.println("writing data to random.ByteBufferDirect.data file");
try {
new FileOutputStream(new File("random.ByteBufferDirect.data")).write(bytes);
} catch (IOException ex) {
ex.printStackTrace();
}
}
private void measure(String name, int size, int loop, Runnable runnable) {
// warm-up
for (int i=0; i < loop; i++) {
runnable.run();
}
long startTime = System.currentTimeMillis();
for (int i=0; i < loop; i++) {
runnable.run();
}
long time = System.currentTimeMillis() - startTime;
double mbs = size * (long) loop / ((double) time / 1000) / 1024 / 1024;
double msec = time / (double) loop;
System.out.printf("-- %s%n", name);
System.out.printf(" %.2f msec/loop%n", msec);
System.out.printf(" %.2f MB/s%n", mbs);
}
private static class ByteBufferRunnable implements Runnable {
private ByteBuffer src;
public int v32;
public long v64;
public ByteBufferRunnable(ByteBuffer src) {
this.src = src;
}
public void run() {
int last = src.limit() - 9;
for(int i=0; i < last; i++) {
byte b = src.get(i);
i++;
if(b < 0) {
v32 = src.getInt(i);
i += 4;
} else {
v64 = src.getLong(i);
i += 8;
}
}
}
}
}
import java.util.Random;
import java.nio.ByteBuffer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class DeserBenchmarkByteBufferHeap {
public static void main(String[] args) throws Exception {
if (args.length != 3) {
System.out.println("usage: <seed> <size> <loop>");
System.exit(1);
}
long seed = Long.parseLong(args[0]);
int size = Integer.parseInt(args[1]);
int loop = Integer.parseInt(args[2]);
new DeserBenchmarkByteBufferHeap().run(seed, size, loop);
}
public void run(long seed, int size, int loop) {
if (seed == 0) {
seed = new Random().nextInt();
}
System.out.printf("seed: %d%n", seed);
System.out.printf("size: %d bytes%n", size);
System.out.printf("loop: %d times%n", loop);
byte[] bytes = new byte[size];
new Random(seed).nextBytes(bytes);
ByteBuffer heap = ByteBuffer.wrap(bytes);
measure("ByteBuffer heap", size, loop, new ByteBufferRunnable(heap));
System.out.println("writing data to random.ByteBufferHeap.data file");
try {
new FileOutputStream(new File("random.ByteBufferHeap.data")).write(bytes);
} catch (IOException ex) {
ex.printStackTrace();
}
}
private void measure(String name, int size, int loop, Runnable runnable) {
// warm-up
for (int i=0; i < loop; i++) {
runnable.run();
}
long startTime = System.currentTimeMillis();
for (int i=0; i < loop; i++) {
runnable.run();
}
long time = System.currentTimeMillis() - startTime;
double mbs = size * (long) loop / ((double) time / 1000) / 1024 / 1024;
double msec = time / (double) loop;
System.out.printf("-- %s%n", name);
System.out.printf(" %.2f msec/loop%n", msec);
System.out.printf(" %.2f MB/s%n", mbs);
}
private static class ByteBufferRunnable implements Runnable {
private ByteBuffer src;
public int v32;
public long v64;
public ByteBufferRunnable(ByteBuffer src) {
this.src = src;
}
public void run() {
int last = src.limit() - 9;
for(int i=0; i < last; i++) {
byte b = src.get(i);
i++;
if(b < 0) {
v32 = src.getInt(i);
i += 4;
} else {
v64 = src.getLong(i);
i += 8;
}
}
}
}
}
import java.util.Random;
import sun.misc.Unsafe;
import sun.nio.ch.DirectBuffer;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class DeserBenchmarkUnsafeDirect {
public static void main(String[] args) throws Exception {
if (args.length != 3) {
System.out.println("usage: <seed> <size> <loop>");
System.exit(1);
}
long seed = Long.parseLong(args[0]);
int size = Integer.parseInt(args[1]);
int loop = Integer.parseInt(args[2]);
new DeserBenchmarkUnsafeDirect().run(seed, size, loop);
}
public void run(long seed, int size, int loop) {
if (seed == 0) {
seed = new Random().nextInt();
}
System.out.printf("seed: %d%n", seed);
System.out.printf("size: %d bytes%n", size);
System.out.printf("loop: %d times%n", loop);
byte[] bytes = new byte[size];
new Random(seed).nextBytes(bytes);
ByteBuffer direct = ByteBuffer.allocateDirect(size);
direct.put(bytes);
measure("Unsafe direct", size, loop, new DirectUnsafeRunnable(direct));
System.out.println("writing data to random.UnsafeDirect.data file");
try {
new FileOutputStream(new File("random.UnsafeDirect.data")).write(bytes);
} catch (IOException ex) {
ex.printStackTrace();
}
}
private void measure(String name, int size, int loop, Runnable runnable) {
// warm-up
for (int i=0; i < loop; i++) {
runnable.run();
}
long startTime = System.currentTimeMillis();
for (int i=0; i < loop; i++) {
runnable.run();
}
long time = System.currentTimeMillis() - startTime;
double mbs = size * (long) loop / ((double) time / 1000) / 1024 / 1024;
double msec = time / (double) loop;
System.out.printf("-- %s%n", name);
System.out.printf(" %.2f msec/loop%n", msec);
System.out.printf(" %.2f MB/s%n", mbs);
}
private static class UnsafeRunnable implements Runnable {
private static final Unsafe unsafe;
public int v32;
public long v64;
static {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Object base;
private long address;
private int length;
public UnsafeRunnable(Object base, long address, int length) {
this.base = base;
this.length = length;
}
public void run() {
int last = length - 9;
for(int i=0; i < last; i++) {
byte b = unsafe.getByte(base, address + i);
i++;
if(b < 0) {
v32 = unsafe.getInt(base, address + i);
i += 4;
} else {
v64 = unsafe.getLong(base, address + i);
i += 8;
}
}
}
}
private static class DirectUnsafeRunnable extends UnsafeRunnable {
public DirectUnsafeRunnable(ByteBuffer src) {
super(src, ((DirectBuffer) src).address(), src.limit());
}
}
}
import java.util.Random;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class DeserBenchmarkUnsafeHeap {
public static void main(String[] args) throws Exception {
if (args.length != 3) {
System.out.println("usage: <seed> <size> <loop>");
System.exit(1);
}
long seed = Long.parseLong(args[0]);
int size = Integer.parseInt(args[1]);
int loop = Integer.parseInt(args[2]);
new DeserBenchmarkUnsafeHeap().run(seed, size, loop);
}
public void run(long seed, int size, int loop) {
if (seed == 0) {
seed = new Random().nextInt();
}
System.out.printf("seed: %d%n", seed);
System.out.printf("size: %d bytes%n", size);
System.out.printf("loop: %d times%n", loop);
byte[] bytes = new byte[size];
new Random(seed).nextBytes(bytes);
measure("Unsafe heap", size, loop, new HeapUnsafeRunnable(bytes));
System.out.println("writing data to random.UnsafeHeap.data file");
try {
new FileOutputStream(new File("random.UnsafeHeap.data")).write(bytes);
} catch (IOException ex) {
ex.printStackTrace();
}
}
private void measure(String name, int size, int loop, Runnable runnable) {
// warm-up
for (int i=0; i < loop; i++) {
runnable.run();
}
long startTime = System.currentTimeMillis();
for (int i=0; i < loop; i++) {
runnable.run();
}
long time = System.currentTimeMillis() - startTime;
double mbs = size * (long) loop / ((double) time / 1000) / 1024 / 1024;
double msec = time / (double) loop;
System.out.printf("-- %s%n", name);
System.out.printf(" %.2f msec/loop%n", msec);
System.out.printf(" %.2f MB/s%n", mbs);
}
private static class UnsafeRunnable implements Runnable {
private static final Unsafe unsafe;
public int v32;
public long v64;
static {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Object base;
private long address;
private int length;
public UnsafeRunnable(Object base, long address, int length) {
this.base = base;
this.length = length;
}
public void run() {
int last = length - 9;
for(int i=0; i < last; i++) {
byte b = unsafe.getByte(base, address + i);
i++;
if(b < 0) {
v32 = unsafe.getInt(base, address + i);
i += 4;
} else {
v64 = unsafe.getLong(base, address + i);
i += 8;
}
}
}
}
private static class HeapUnsafeRunnable extends UnsafeRunnable {
public HeapUnsafeRunnable(byte[] src) {
super(src, Unsafe.ARRAY_BYTE_BASE_OFFSET, src.length);
}
}
}
all: run
DeserBenchmark.class: DeserBenchmark.java
javac -version
javac DeserBenchmark.java
DeserBenchmarkByteBufferHeap.class: DeserBenchmarkByteBufferHeap.java
javac -version
javac DeserBenchmarkByteBufferHeap.java
DeserBenchmarkByteBufferDirect.class: DeserBenchmarkByteBufferDirect.java
javac -version
javac DeserBenchmarkByteBufferDirect.java
DeserBenchmarkUnsafeHeap.class: DeserBenchmarkUnsafeHeap.java
javac -version
javac DeserBenchmarkUnsafeHeap.java
DeserBenchmarkUnsafeDirect.class: DeserBenchmarkUnsafeDirect.java
javac -version
javac DeserBenchmarkUnsafeDirect.java
run: DeserBenchmark.class DeserBenchmarkByteBufferDirect.class DeserBenchmarkByteBufferHeap.class DeserBenchmarkUnsafeDirect.class DeserBenchmarkUnsafeHeap.class
uname -a
cat /proc/cpuinfo | grep "model name"
free -h
java -version
java -cp . DeserBenchmark 1700461846 10000000 1000
java -cp . DeserBenchmarkByteBufferHeap 1700461846 10000000 1000
java -cp . DeserBenchmarkByteBufferDirect 1700461846 10000000 1000
java -cp . DeserBenchmarkUnsafeHeap 1700461846 10000000 1000
java -cp . DeserBenchmarkUnsafeDirect 1700461846 10000000 1000
clean:
rm -f *.class
rm -f random.data
rm -f random.*.data
.PHONY: clean run
javac -version
javac 1.7.0_45
javac DeserBenchmark.java
DeserBenchmark.java:3: warning: Unsafe is internal proprietary API and may be removed in a future release
import sun.misc.Unsafe;
^
DeserBenchmark.java:4: warning: DirectBuffer is internal proprietary API and may be removed in a future release
import sun.nio.ch.DirectBuffer;
^
DeserBenchmark.java:100: warning: Unsafe is internal proprietary API and may be removed in a future release
private static final Unsafe unsafe;
^
DeserBenchmark.java:107: warning: Unsafe is internal proprietary API and may be removed in a future release
Field field = Unsafe.class.getDeclaredField("theUnsafe");
^
DeserBenchmark.java:109: warning: Unsafe is internal proprietary API and may be removed in a future release
unsafe = (Unsafe) field.get(null);
^
DeserBenchmark.java:142: warning: Unsafe is internal proprietary API and may be removed in a future release
super(src, Unsafe.ARRAY_BYTE_BASE_OFFSET, src.length);
^
DeserBenchmark.java:148: warning: DirectBuffer is internal proprietary API and may be removed in a future release
super(src, ((DirectBuffer) src).address(), src.limit());
^
7 warnings
javac -version
javac 1.7.0_45
javac DeserBenchmarkByteBufferDirect.java
javac -version
javac 1.7.0_45
javac DeserBenchmarkByteBufferHeap.java
javac -version
javac 1.7.0_45
javac DeserBenchmarkUnsafeDirect.java
DeserBenchmarkUnsafeDirect.java:3: warning: Unsafe is internal proprietary API and may be removed in a future release
import sun.misc.Unsafe;
^
DeserBenchmarkUnsafeDirect.java:4: warning: DirectBuffer is internal proprietary API and may be removed in a future release
import sun.nio.ch.DirectBuffer;
^
DeserBenchmarkUnsafeDirect.java:69: warning: Unsafe is internal proprietary API and may be removed in a future release
private static final Unsafe unsafe;
^
DeserBenchmarkUnsafeDirect.java:76: warning: Unsafe is internal proprietary API and may be removed in a future release
Field field = Unsafe.class.getDeclaredField("theUnsafe");
^
DeserBenchmarkUnsafeDirect.java:78: warning: Unsafe is internal proprietary API and may be removed in a future release
unsafe = (Unsafe) field.get(null);
^
DeserBenchmarkUnsafeDirect.java:111: warning: DirectBuffer is internal proprietary API and may be removed in a future release
super(src, ((DirectBuffer) src).address(), src.limit());
^
6 warnings
javac -version
javac 1.7.0_45
javac DeserBenchmarkUnsafeHeap.java
DeserBenchmarkUnsafeHeap.java:3: warning: Unsafe is internal proprietary API and may be removed in a future release
import sun.misc.Unsafe;
^
DeserBenchmarkUnsafeHeap.java:65: warning: Unsafe is internal proprietary API and may be removed in a future release
private static final Unsafe unsafe;
^
DeserBenchmarkUnsafeHeap.java:72: warning: Unsafe is internal proprietary API and may be removed in a future release
Field field = Unsafe.class.getDeclaredField("theUnsafe");
^
DeserBenchmarkUnsafeHeap.java:74: warning: Unsafe is internal proprietary API and may be removed in a future release
unsafe = (Unsafe) field.get(null);
^
DeserBenchmarkUnsafeHeap.java:107: warning: Unsafe is internal proprietary API and may be removed in a future release
super(src, Unsafe.ARRAY_BYTE_BASE_OFFSET, src.length);
^
5 warnings
uname -a
Linux banana 5.8.0-53-generic #60~20.04.1-Ubuntu SMP Thu May 6 09:52:46 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
cat /proc/cpuinfo | grep "model name"
model name : Intel(R) Xeon(R) CPU E5-1620 0 @ 3.60GHz
model name : Intel(R) Xeon(R) CPU E5-1620 0 @ 3.60GHz
model name : Intel(R) Xeon(R) CPU E5-1620 0 @ 3.60GHz
model name : Intel(R) Xeon(R) CPU E5-1620 0 @ 3.60GHz
model name : Intel(R) Xeon(R) CPU E5-1620 0 @ 3.60GHz
model name : Intel(R) Xeon(R) CPU E5-1620 0 @ 3.60GHz
model name : Intel(R) Xeon(R) CPU E5-1620 0 @ 3.60GHz
model name : Intel(R) Xeon(R) CPU E5-1620 0 @ 3.60GHz
free -h
total used free shared buff/cache available
Mem: 15Gi 2.0Gi 9.3Gi 10Mi 4.3Gi 13Gi
Swap: 30Gi 0B 30Gi
java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
java -cp . DeserBenchmark 1700461846 10000000 1000
seed: 1700461846
size: 10000000 bytes
loop: 1000 times
-- ByteBuffer heap
12.04 msec/loop
792.29 MB/s
-- ByteBuffer direct
8.64 msec/loop
1103.53 MB/s
-- Unsafe heap
5.96 msec/loop
1600.93 MB/s
-- Unsafe direct
5.51 msec/loop
1731.75 MB/s
writing data to random.data file
java -cp . DeserBenchmarkByteBufferHeap 1700461846 10000000 1000
seed: 1700461846
size: 10000000 bytes
loop: 1000 times
-- ByteBuffer heap
12.04 msec/loop
792.02 MB/s
writing data to random.ByteBufferHeap.data file
java -cp . DeserBenchmarkByteBufferDirect 1700461846 10000000 1000
seed: 1700461846
size: 10000000 bytes
loop: 1000 times
-- ByteBuffer direct
6.29 msec/loop
1516.66 MB/s
writing data to random.ByteBufferDirect.data file
java -cp . DeserBenchmarkUnsafeHeap 1700461846 10000000 1000
seed: 1700461846
size: 10000000 bytes
loop: 1000 times
-- Unsafe heap
5.96 msec/loop
1601.20 MB/s
writing data to random.UnsafeHeap.data file
java -cp . DeserBenchmarkUnsafeDirect 1700461846 10000000 1000
seed: 1700461846
size: 10000000 bytes
loop: 1000 times
-- Unsafe direct
5.51 msec/loop
1732.38 MB/s
writing data to random.UnsafeDirect.data file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment