Skip to content

Commit

Permalink
60: Improve BufferedData Performance (#120)
Browse files Browse the repository at this point in the history
Fixes: #60
Reviewed-by: Ivan Malygin <ivan@swirldslabs.com>, Richard Bair <richard@swirldslabs.com>
Signed-off-by: Artem Ananev <artem.ananev@swirldslabs.com>
  • Loading branch information
artemananiev authored Nov 29, 2023
1 parent e903783 commit adaa794
Show file tree
Hide file tree
Showing 15 changed files with 1,783 additions and 462 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package com.hedera.pbj.runtime.io;

import com.hedera.pbj.runtime.io.buffer.BufferedData;
import com.hedera.pbj.runtime.io.buffer.Bytes;
import java.nio.ByteBuffer;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.infra.Blackhole;

@Fork(value = 1)
@State(Scope.Benchmark)
public class BufferedDataGetBytes {

@Param({"10000"})
public int size = 10000;

@Param({"1000"})
public int window = 1000;

private BufferedData heapData;
private BufferedData directData;

private boolean printSum;

@Setup(Level.Trial)
public void init() {
heapData = BufferedData.allocate(size);
directData = BufferedData.allocateOffHeap(size);
for (int i = 0; i < size; i++) {
heapData.writeByte((byte) (i % 111));
directData.writeByte((byte) (i % 111));
}
}

@Setup(Level.Iteration)
public void initEach() {
printSum = true;
}

private static long sum(final byte[] arr) {
long result = 0;
for (int i = 0; i < arr.length; i++) {
result += arr[i];
}
return result;
}

private static long sum(final ByteBuffer buf) {
long result = 0;
for (int i = 0; i < buf.capacity(); i++) {
result += buf.get(i);
}
return result;
}

private static long sum(final Bytes bytes) {
long result = 0;
for (int i = 0; i < bytes.length(); i++) {
result += bytes.getByte(i);
}
return result;
}

@Benchmark
public void heapToByteArray(final Blackhole blackhole) {
final byte[] dst = new byte[window];
long sum = 0;
for (int i = 0; i < size - window; i++) {
heapData.getBytes(i, dst);
// sum += sum(dst);
blackhole.consume(dst);
}
if (printSum) {
// System.out.println("sum = " + sum);
printSum = false;
}
blackhole.consume(sum);
}

@Benchmark
public void heapToHeapByteBuffer(final Blackhole blackhole) {
final ByteBuffer dst = ByteBuffer.allocate(window);
long sum = 0;
for (int i = 0; i < size - window; i++) {
heapData.getBytes(i, dst);
// sum += sum(dst);
blackhole.consume(dst);
}
if (printSum) {
// System.out.println("sum = " + sum);
printSum = false;
}
blackhole.consume(sum);
}

@Benchmark
public void heapToDirectByteBuffer(final Blackhole blackhole) {
final ByteBuffer dst = ByteBuffer.allocateDirect(window);
long sum = 0;
for (int i = 0; i < size - window; i++) {
heapData.getBytes(i, dst);
// sum += sum(dst);
blackhole.consume(dst);
}
if (printSum) {
// System.out.println("sum = " + sum);
printSum = false;
}
blackhole.consume(sum);
}

@Benchmark
public void heapToBytes(final Blackhole blackhole) {
long sum = 0;
for (int i = 0; i < size - window; i++) {
final Bytes bytes = heapData.getBytes(i, window);
// sum += sum(bytes);
blackhole.consume(bytes);
}
if (printSum) {
// System.out.println("sum = " + sum);
printSum = false;
}
blackhole.consume(sum);
}

@Benchmark
public void directToByteArray(final Blackhole blackhole) {
final byte[] dst = new byte[window];
long sum = 0;
for (int i = 0; i < size - window; i++) {
directData.getBytes(i, dst);
// sum += sum(dst);
blackhole.consume(dst);
}
if (printSum) {
// System.out.println("sum = " + sum);
printSum = false;
}
blackhole.consume(sum);
}

@Benchmark
public void directToHeapByteBuffer(final Blackhole blackhole) {
final ByteBuffer dst = ByteBuffer.allocate(window);
long sum = 0;
for (int i = 0; i < size - window; i++) {
directData.getBytes(i, dst);
// sum += sum(dst);
blackhole.consume(dst);
}
if (printSum) {
// System.out.println("sum = " + sum);
printSum = false;
}
blackhole.consume(sum);
}

@Benchmark
public void directToDirectByteBuffer(final Blackhole blackhole) {
final ByteBuffer dst = ByteBuffer.allocateDirect(window);
long sum = 0;
for (int i = 0; i < size - window; i++) {
directData.getBytes(i, dst);
// sum += sum(dst);
blackhole.consume(dst);
}
if (printSum) {
// System.out.println("sum = " + sum);
printSum = false;
}
blackhole.consume(sum);
}

@Benchmark
public void directToBytes(final Blackhole blackhole) {
long sum = 0;
for (int i = 0; i < size - window; i++) {
final Bytes bytes = directData.getBytes(i, window);
// sum += sum(bytes);
blackhole.consume(bytes);
}
if (printSum) {
// System.out.println("sum = " + sum);
printSum = false;
}
blackhole.consume(sum);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package com.hedera.pbj.runtime.io;

import java.nio.ByteBuffer;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.infra.Blackhole;

@Fork(value = 1)
@State(Scope.Benchmark)
public class ByteBufferGetByte {

@Param({"10000"})
public int size = 10000;

private ByteBuffer heapBuffer;
private ByteBuffer directBuffer;

private boolean printSum;

@Setup(Level.Trial)
public void init() {
heapBuffer = ByteBuffer.allocate(size);
directBuffer = ByteBuffer.allocateDirect(size);
for (int i = 0; i < size; i++) {
heapBuffer.put((byte) (i % 111));
directBuffer.put((byte) (i % 111));
}
}

@Setup(Level.Iteration)
public void initEach() {
printSum = true;
}

@Setup(Level.Invocation)
public void initEachInvocation() {
heapBuffer.clear();
directBuffer.clear();
}

@Benchmark
public void heapArrayGet(final Blackhole blackhole) {
long sum = 0;
final byte[] array = heapBuffer.array();
for (int i = 0; i < size; i++) {
// sum += array[i];
blackhole.consume(array[i]);
}
if (printSum) {
System.out.println("sum = " + sum);
printSum = false;
}
blackhole.consume(sum);
}

@Benchmark
public void heapBufferGet(final Blackhole blackhole) {
long sum = 0;
for (int i = 0; i < size; i++) {
// sum += heapBuffer.get(i);
blackhole.consume(heapBuffer.get(i));
}
if (printSum) {
System.out.println("sum = " + sum);
printSum = false;
}
blackhole.consume(sum);
}

@Benchmark
public void heapBufferRead(final Blackhole blackhole) {
long sum = 0;
for (int i = 0; i < size; i++) {
// sum += heapBuffer.get();
blackhole.consume(heapBuffer.get());
}
if (printSum) {
System.out.println("sum = " + sum);
printSum = false;
}
blackhole.consume(sum);
}

@Benchmark
public void directBufferGet(final Blackhole blackhole) {
long sum = 0;
for (int i = 0; i < size; i++) {
// sum += directBuffer.get(i);
blackhole.consume(directBuffer.get(i));
}
if (printSum) {
System.out.println("sum = " + sum);
printSum = false;
}
blackhole.consume(sum);
}

@Benchmark
public void heapUnsafeGet(final Blackhole blackhole) {
long sum = 0;
for (int i = 0; i < size; i++) {
// sum += UnsafeUtils.getByteHeap(heapBuffer, i);
blackhole.consume(UnsafeUtils.getByteHeap(heapBuffer, i));
}
if (printSum) {
System.out.println("sum = " + sum);
printSum = false;
}
blackhole.consume(sum);
}

@Benchmark
public void directUnsafeGet(final Blackhole blackhole) {
long sum = 0;
for (int i = 0; i < size; i++) {
// sum += UnsafeUtils.getByteDirect(directBuffer, i);
blackhole.consume(UnsafeUtils.getByteDirect(directBuffer, i));
}
if (printSum) {
System.out.println("sum = " + sum);
printSum = false;
}
blackhole.consume(sum);
}

}
Loading

0 comments on commit adaa794

Please sign in to comment.