//Copy right 2020 Jacky Zong.All rights reserved.
package encyrption;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
public class MemoryAccessMain {
public static final int ARRAY_BYTE_BASE_OFFSET;
public static final int ARRAY_INT_BASE_OFFSET;
static final String text = "0123456789" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"abcdefghijklmnopqrstuvwxyz-_" +
"0123456789" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"abcdefghijklmnopqrstuvwxyz-_";
static final Unsafe UNSAFE;
static final int ARRAY_LONG_BASE_OFFSET;
private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
static byte[] byteArray = text.getBytes(ISO_8859_1);
static int[] intArray = new int[byteArray.length / 4];
static int[] longArray = new int[byteArray.length / 8];
static ByteBuffer bb = ByteBuffer.allocateDirect(text.length());
static {
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
UNSAFE = (Unsafe) theUnsafe.get(null);
ARRAY_BYTE_BASE_OFFSET = UNSAFE.arrayBaseOffset(byte[].class);
ARRAY_INT_BASE_OFFSET = UNSAFE.arrayBaseOffset(int[].class);
ARRAY_LONG_BASE_OFFSET = UNSAFE.arrayBaseOffset(long[].class);
UNSAFE.copyMemory(byteArray, ARRAY_BYTE_BASE_OFFSET, intArray, ARRAY_INT_BASE_OFFSET, byteArray.length);
;
UNSAFE.copyMemory(byteArray, ARRAY_BYTE_BASE_OFFSET, longArray, ARRAY_LONG_BASE_OFFSET, byteArray.length);
for (int i = 0; i < text.length(); i++)
bb.put((byte) text.charAt(i));
} catch (Exception e) {
throw new AssertionError(e);
}
}
static long address(ByteBuffer bb) {
return ((sun.nio.ch.DirectBuffer) bb).address();
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(MemoryAccessMain.class.getSimpleName())
.forks(9)
.build();
new Runner(opt).run();
}
@Benchmark
public long checkSumWithCopyByByte() {
UNSAFE.copyMemory(null, address(bb), byteArray, ARRAY_BYTE_BASE_OFFSET, byteArray.length);
long sum = 0;
for (byte b : byteArray)
sum += b;
return sum;
}
@Benchmark
public long checkSumWithCopyByInt() {
UNSAFE.copyMemory(null, address(bb), intArray, ARRAY_INT_BASE_OFFSET, intArray.length * 4);
long sum = 0;
for (int b : intArray)
sum += b;
return sum;
}
@Benchmark
public long checkSumWithCopyByLong() {
UNSAFE.copyMemory(null, address(bb), longArray, ARRAY_LONG_BASE_OFFSET, longArray.length * 8);
long sum = 0;
for (long l : longArray)
sum += l;
return sum;
}
@Benchmark
public long checkSumByteBufferByByte() {
long sum = 0;
int len = bb.capacity();
for (int i = 0; i < len; i++)
sum += bb.get(i);
return sum;
}
@Benchmark
public long checkSumByteBufferByInt() {
long sum = 0;
int len = bb.capacity();
for (int i = 0; i < len; i += 4)
sum += bb.getInt(i);
return sum;
}
@Benchmark
public long checkSumByteBufferByLong() {
long sum = 0;
int len = bb.capacity();
for (int i = 0; i < len; i += 8)
sum += bb.getLong(i);
return sum;
}
@Benchmark
public long checkSumNativeMemoryByByte() {
long sum = 0;
long address = address(bb);
int len = bb.capacity();
for (int i = 0; i < len; i++)
sum += UNSAFE.getByte(address + i);
return sum;
}
@Benchmark
public long checkSumNativeMemoryByInt() {
long sum = 0;
long address = address(bb);
int len = bb.capacity();
for (int i = 0; i < len; i += 4)
sum += UNSAFE.getInt(address + i);
return sum;
}
@Benchmark
public long checkSumNativeMemoryByLong() {
long sum = 0;
long address = address(bb);
int len = bb.capacity();
for (int i = 0; i < len; i += 8)
sum += UNSAFE.getLong(address + i);
return sum;
}
}