You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ta...@apache.org on 2018/12/07 19:41:36 UTC
[2/2] qpid-proton-j git commit: PROTON-1980 Optimize the
CompositeReadableBuffer hashCode method
PROTON-1980 Optimize the CompositeReadableBuffer hashCode method
Optimize hashCode to better deal with multiple array contents when
producing the hashCode. Adds additional JMH tests to cover this area.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton-j/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton-j/commit/31a0b35f
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton-j/tree/31a0b35f
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton-j/diff/31a0b35f
Branch: refs/heads/master
Commit: 31a0b35f05794fcbbcf906bc6b921148ac65a27a
Parents: 068f4d0
Author: Timothy Bish <ta...@gmail.com>
Authored: Fri Dec 7 14:41:16 2018 -0500
Committer: Timothy Bish <ta...@gmail.com>
Committed: Fri Dec 7 14:41:16 2018 -0500
----------------------------------------------------------------------
.../proton/codec/CompositeReadableBuffer.java | 51 +++--
.../codec/CompositeReadableBufferTest.java | 37 ++++
.../codec/CompositeReadableBufferBenchmark.java | 207 ++++++++++++++-----
.../CompositeReadableBufferEqualsBenchmark.java | 108 ++++++++++
...siteReadableBufferStringDecodeBenchmark.java | 110 ----------
5 files changed, 337 insertions(+), 176 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/31a0b35f/proton-j/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBuffer.java
----------------------------------------------------------------------
diff --git a/proton-j/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBuffer.java b/proton-j/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBuffer.java
index 5310faf..3aec96c 100644
--- a/proton-j/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBuffer.java
+++ b/proton-j/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBuffer.java
@@ -702,11 +702,11 @@ public class CompositeReadableBuffer implements ReadableBuffer {
}
private void validateBuffer(ReadableBuffer buffer) {
- if(buffer == null) {
+ if (buffer == null) {
throw new IllegalArgumentException("A non-null buffer must be provided");
}
- if(!buffer.hasRemaining()) {
+ if (!buffer.hasRemaining()) {
throw new IllegalArgumentException("Buffer has no remaining content to append");
}
}
@@ -739,8 +739,7 @@ public class CompositeReadableBuffer implements ReadableBuffer {
do {
int bufferRemaining = buffer.remaining();
int arrayRemaining = buffer.currentArray.length - buffer.currentOffset;
- if (buffer.currentOffset > 0 || bufferRemaining < arrayRemaining)
- {
+ if (buffer.currentOffset > 0 || bufferRemaining < arrayRemaining) {
int length = Math.min(arrayRemaining, bufferRemaining);
chunk = new byte[length];
System.arraycopy(buffer.currentArray, buffer.currentOffset, chunk, 0, length);
@@ -783,7 +782,7 @@ public class CompositeReadableBuffer implements ReadableBuffer {
validateAppendable();
validateBuffer(buffer);
- if(buffer.hasArray()) {
+ if (buffer.hasArray()) {
byte[] chunk = buffer.array();
int bufferRemaining = buffer.remaining();
@@ -809,16 +808,44 @@ public class CompositeReadableBuffer implements ReadableBuffer {
@Override
public int hashCode() {
int hash = 1;
+ int remaining = remaining();
- if (currentArrayIndex < 0) {
- int span = limit() - position();
- while (span > 0) {
- hash = 31 * hash + currentArray[currentOffset + --span];
+ if (currentArrayIndex < 0 || remaining <= currentArray.length - currentOffset) {
+ while (remaining > 0) {
+ hash = 31 * hash + currentArray[currentOffset + --remaining];
}
} else {
- final int currentPos = position();
- for (int i = limit() - 1; i >= currentPos; i--) {
- hash = 31 * hash + (int)get(i);
+ hash = hashCodeFromComponents();
+ }
+
+ return hash;
+ }
+
+ private int hashCodeFromComponents() {
+ int hash = 1;
+ byte[] array = currentArray;
+ int arrayOffset = currentOffset;
+ int arraysIndex = currentArrayIndex;
+
+ // Run to the the array and offset where we want to start the hash from
+ final int remaining = remaining();
+ for (int moveBy = remaining; moveBy > 0; ) {
+ if (moveBy <= array.length - arrayOffset) {
+ arrayOffset += moveBy;
+ break;
+ } else {
+ moveBy -= array.length - arrayOffset;
+ array = contents.get(++arraysIndex);
+ arrayOffset = 0;
+ }
+ }
+
+ // Now run backwards through the arrays to match what ByteBuffer would produce
+ for (int moveBy = remaining; moveBy > 0; moveBy--) {
+ hash = 31 * hash + array[--arrayOffset];
+ if (arrayOffset == 0 && arraysIndex > 0) {
+ array = contents.get(--arraysIndex);
+ arrayOffset = array.length;
}
}
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/31a0b35f/proton-j/src/test/java/org/apache/qpid/proton/codec/CompositeReadableBufferTest.java
----------------------------------------------------------------------
diff --git a/proton-j/src/test/java/org/apache/qpid/proton/codec/CompositeReadableBufferTest.java b/proton-j/src/test/java/org/apache/qpid/proton/codec/CompositeReadableBufferTest.java
index 84c63f7..28d5d17 100644
--- a/proton-j/src/test/java/org/apache/qpid/proton/codec/CompositeReadableBufferTest.java
+++ b/proton-j/src/test/java/org/apache/qpid/proton/codec/CompositeReadableBufferTest.java
@@ -3398,6 +3398,20 @@ public class CompositeReadableBufferTest {
}
@Test
+ public void testHashCodeMatchesByteBufferWhenLimitSetGivesNoRemaining() throws CharacterCodingException {
+ byte[] data = new byte[] {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
+
+ CompositeReadableBuffer buffer1 = new CompositeReadableBuffer();
+ buffer1.append(data);
+ buffer1.limit(10);
+
+ ByteBuffer buffer2 = ByteBuffer.wrap(data);
+ buffer2.limit(10);
+
+ assertEquals(buffer1.hashCode(), buffer2.hashCode());
+ }
+
+ @Test
public void testHashCodeMatchesByteBufferSingleArrayContents() throws CharacterCodingException {
byte[] data = new byte[] {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
@@ -3459,6 +3473,29 @@ public class CompositeReadableBufferTest {
assertEquals(slice1.hashCode(), slice2.hashCode());
}
+ @Test
+ public void testHashCodeMatchesByteBufferMultipleArrayContentsWithRangeOfLimits() throws CharacterCodingException {
+ byte[] data = new byte[] {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
+
+ byte[] data1 = new byte[] {10, 9};
+ byte[] data2 = new byte[] {8, 7};
+ byte[] data3 = new byte[] {6, 5, 4};
+ byte[] data4 = new byte[] {3};
+ byte[] data5 = new byte[] {2, 1, 0};
+
+ CompositeReadableBuffer buffer1 = new CompositeReadableBuffer();
+ buffer1.append(data1).append(data2).append(data3).append(data4).append(data5);
+
+ ByteBuffer buffer2 = ByteBuffer.wrap(data);
+
+ for (int i = 0; i < data.length; ++i) {
+ buffer1.limit(i);
+ buffer2.limit(i);
+
+ assertEquals(buffer1.hashCode(), buffer2.hashCode());
+ }
+ }
+
//----- Tests for equals -------------------------------------------------//
@Test
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/31a0b35f/tests/performance-jmh/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBufferBenchmark.java
----------------------------------------------------------------------
diff --git a/tests/performance-jmh/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBufferBenchmark.java b/tests/performance-jmh/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBufferBenchmark.java
index 4eda8fd..f05b91a 100644
--- a/tests/performance-jmh/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBufferBenchmark.java
+++ b/tests/performance-jmh/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBufferBenchmark.java
@@ -1,36 +1,43 @@
-/**
+/*
* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
+ * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.apache.qpid.proton.codec;
-import org.apache.qpid.proton.codec.ReadableBuffer.ByteBufferReader;
-import org.openjdk.jmh.annotations.*;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.profile.GCProfiler;
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 java.nio.ByteBuffer;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test performance of the CompositeReadableBuffer class
- */
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@@ -38,62 +45,154 @@ import java.util.concurrent.TimeUnit;
@Measurement(iterations = 5, time = 1)
public class CompositeReadableBufferBenchmark {
- private CompositeReadableBuffer composite;
- @Param({"8", "64", "1024"})
- private int size;
- private ReadableBuffer.ByteBufferReader bufferReader;
- @Param({"false", "true"})
- private boolean direct;
- @Param({"1", "2"})
- private int chunks;
- private CompositeReadableBuffer compositePartial;
- private ReadableBuffer bufferReaderPartial;
+ private static final String PAYLOAD =
+ "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
+ + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
+ + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
+ + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
+ + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
+
+ private static final String PAYLOAD_CHUNK =
+ "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
+
+ private final CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
+
+ private CompositeReadableBuffer singleArrayString;
+ private CompositeReadableBuffer splitArrayString;
+
+ private Blackhole blackhole;
@Setup
- public void init() {
- bufferReader =
- direct ? ByteBufferReader.wrap(ByteBuffer.allocateDirect(size)) : ByteBufferReader.wrap(new byte[size]);
- composite = new CompositeReadableBuffer();
- int sizePerChunk = size / chunks;
- for (int i = 0; i < chunks; i++) {
- final byte[] content = new byte[sizePerChunk];
- composite.append(content);
- }
- int remaining = size - composite.capacity();
- if (remaining > 0) {
- byte[] lastChunk = new byte[remaining];
- composite.append(lastChunk);
+ public void init(Blackhole blackhole) {
+ this.blackhole = blackhole;
+
+ byte[] payload = PAYLOAD.getBytes(StandardCharsets.UTF_8);
+
+ singleArrayString = new CompositeReadableBuffer();
+ singleArrayString.append(Arrays.copyOf(payload, payload.length));
+
+ byte[] payloadChunk = PAYLOAD_CHUNK.getBytes(StandardCharsets.UTF_8);
+
+ splitArrayString = new CompositeReadableBuffer();
+
+ for (int i = 0; i < 5; i++) {
+ splitArrayString.append(Arrays.copyOf(payloadChunk, payloadChunk.length));
}
+ }
+
+ @Benchmark
+ public void hashCodeSingleArrayFullSpan() {
+ blackhole.consume(singleArrayString.rewind().hashCode());
+ }
+
+ @Benchmark
+ public void hashCodeMultipleArrayFullSpan() throws CharacterCodingException {
+ blackhole.consume(splitArrayString.rewind().hashCode());
+ }
+
+ @Benchmark
+ public void hashCodeSingArraySpanInSingleArray() throws CharacterCodingException {
+ blackhole.consume(singleArrayString.rewind().limit(PAYLOAD_CHUNK.length()).hashCode());
+ }
+
+ @Benchmark
+ public void hashCodeMultipleArraySpanInSingleArray() throws CharacterCodingException {
+ blackhole.consume(splitArrayString.rewind().limit(PAYLOAD_CHUNK.length()).hashCode());
+ }
+
+ @Benchmark
+ public void readStringSingleArray() throws CharacterCodingException {
+ blackhole.consume(singleArrayString.rewind().readString(decoder.reset()));
+ }
+
+ @Benchmark
+ public void readStringMultiArray() throws CharacterCodingException {
+ blackhole.consume(splitArrayString.rewind().readString(decoder.reset()));
+ }
- compositePartial = composite.duplicate().limit(sizePerChunk);
- bufferReaderPartial = bufferReader.duplicate().limit(sizePerChunk);
+ @Benchmark
+ public void sliceSingleArrayFullSpan() {
+ blackhole.consume(singleArrayString.rewind().slice());
+ }
+
+ @Benchmark
+ public void sliceMultipleArrayFullSpan() {
+ blackhole.consume(splitArrayString.rewind().slice());
+ }
+
+ @Benchmark
+ public void duplicateSingleArrayFullSpan() {
+ blackhole.consume(singleArrayString.rewind().duplicate());
+ }
+
+ @Benchmark
+ public void duplicateMultipleArrayFullSpan() {
+ blackhole.consume(splitArrayString.rewind().duplicate());
+ }
+
+ @Benchmark
+ public void getFromSingleArray() {
+ blackhole.consume(singleArrayString.rewind().get());
+ }
+
+ @Benchmark
+ public void getFromMultipleArray() {
+ blackhole.consume(splitArrayString.rewind().get());
+ }
+
+ @Benchmark
+ public void getShortFromSingleArray() {
+ blackhole.consume(singleArrayString.rewind().getShort());
+ }
+
+ @Benchmark
+ public void getShortFromMultipleArray() {
+ blackhole.consume(splitArrayString.rewind().getShort());
+ }
+
+ @Benchmark
+ public void getIntFromSingleArray() {
+ blackhole.consume(singleArrayString.rewind().getInt());
+ }
+
+ @Benchmark
+ public void getIntFromMultipleArray() {
+ blackhole.consume(splitArrayString.rewind().getInt());
+ }
+
+ @Benchmark
+ public void getLongFromSingleArray() {
+ blackhole.consume(singleArrayString.rewind().getLong());
+ }
+
+ @Benchmark
+ public void getLongFromMultipleArray() {
+ blackhole.consume(splitArrayString.rewind().getLong());
}
@Benchmark
- public boolean equalsToByteBufferReader() {
- composite.position(0);
- return composite.equals(bufferReader);
+ public void positionSingleArrayHalfPlusOne() {
+ blackhole.consume(singleArrayString.rewind().position((singleArrayString.remaining() / 2) + 1));
}
@Benchmark
- public boolean equalsToWithSingleArraySubsetOfBuffer() {
- compositePartial.position(0);
- return compositePartial.equals(bufferReaderPartial);
+ public void positionMultiArrayHalfPlusOne() {
+ blackhole.consume(splitArrayString.rewind().position((splitArrayString.remaining() / 2) + 1));
}
public static void main(String[] args) throws RunnerException {
- runBenchmark(CompositeReadableBuffer.class);
+ runBenchmark(CompositeReadableBufferBenchmark.class);
}
public static void runBenchmark(Class<?> benchmarkClass) throws RunnerException {
final Options opt = new OptionsBuilder()
- .include(benchmarkClass.getSimpleName())
- .addProfiler(GCProfiler.class)
- .shouldDoGC(true)
- .warmupIterations(5)
- .measurementIterations(5)
- .forks(1)
- .build();
+ .include(benchmarkClass.getSimpleName())
+ .addProfiler(GCProfiler.class)
+ .shouldDoGC(true)
+ .warmupIterations(5)
+ .measurementIterations(5)
+ .forks(1)
+ .build();
new Runner(opt).run();
}
}
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/31a0b35f/tests/performance-jmh/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBufferEqualsBenchmark.java
----------------------------------------------------------------------
diff --git a/tests/performance-jmh/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBufferEqualsBenchmark.java b/tests/performance-jmh/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBufferEqualsBenchmark.java
new file mode 100644
index 0000000..dc6b0ef
--- /dev/null
+++ b/tests/performance-jmh/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBufferEqualsBenchmark.java
@@ -0,0 +1,108 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.qpid.proton.codec;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.qpid.proton.codec.ReadableBuffer.ByteBufferReader;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+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.annotations.Warmup;
+import org.openjdk.jmh.profile.GCProfiler;
+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;
+
+/**
+ * Test performance of the CompositeReadableBuffer class when calling equals
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@Warmup(iterations = 5, time = 1)
+@Measurement(iterations = 5, time = 1)
+public class CompositeReadableBufferEqualsBenchmark {
+
+ private CompositeReadableBuffer composite;
+ @Param({"8", "64", "1024"})
+ private int size;
+ private ReadableBuffer.ByteBufferReader bufferReader;
+ @Param({"false", "true"})
+ private boolean direct;
+ @Param({"1", "2"})
+ private int chunks;
+ private CompositeReadableBuffer compositePartial;
+ private ReadableBuffer bufferReaderPartial;
+
+ @Setup
+ public void init() {
+ bufferReader = direct ? ByteBufferReader.wrap(ByteBuffer.allocateDirect(size)) : ByteBufferReader.wrap(new byte[size]);
+ composite = new CompositeReadableBuffer();
+ int sizePerChunk = size / chunks;
+ for (int i = 0; i < chunks; i++) {
+ final byte[] content = new byte[sizePerChunk];
+ composite.append(content);
+ }
+ int remaining = size - composite.capacity();
+ if (remaining > 0) {
+ byte[] lastChunk = new byte[remaining];
+ composite.append(lastChunk);
+ }
+
+ compositePartial = composite.duplicate().limit(sizePerChunk);
+ bufferReaderPartial = bufferReader.duplicate().limit(sizePerChunk);
+ }
+
+ @SuppressWarnings("unlikely-arg-type")
+ @Benchmark
+ public boolean equalsToByteBufferReader() {
+ composite.position(0);
+ return composite.equals(bufferReader);
+ }
+
+ @Benchmark
+ public boolean equalsToWithSingleArraySubsetOfBuffer() {
+ compositePartial.position(0);
+ return compositePartial.equals(bufferReaderPartial);
+ }
+
+ public static void main(String[] args) throws RunnerException {
+ runBenchmark(CompositeReadableBufferEqualsBenchmark.class);
+ }
+
+ public static void runBenchmark(Class<?> benchmarkClass) throws RunnerException {
+ final Options opt = new OptionsBuilder()
+ .include(benchmarkClass.getSimpleName())
+ .addProfiler(GCProfiler.class)
+ .shouldDoGC(true)
+ .warmupIterations(5)
+ .measurementIterations(5)
+ .forks(1)
+ .build();
+ new Runner(opt).run();
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/31a0b35f/tests/performance-jmh/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBufferStringDecodeBenchmark.java
----------------------------------------------------------------------
diff --git a/tests/performance-jmh/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBufferStringDecodeBenchmark.java b/tests/performance-jmh/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBufferStringDecodeBenchmark.java
deleted file mode 100644
index ac1cbb0..0000000
--- a/tests/performance-jmh/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBufferStringDecodeBenchmark.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.qpid.proton.codec;
-
-import java.nio.charset.CharacterCodingException;
-import java.nio.charset.CharsetDecoder;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.concurrent.TimeUnit;
-
-import org.openjdk.jmh.annotations.Benchmark;
-import org.openjdk.jmh.annotations.BenchmarkMode;
-import org.openjdk.jmh.annotations.Measurement;
-import org.openjdk.jmh.annotations.Mode;
-import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.Setup;
-import org.openjdk.jmh.annotations.State;
-import org.openjdk.jmh.annotations.Warmup;
-import org.openjdk.jmh.infra.Blackhole;
-import org.openjdk.jmh.profile.GCProfiler;
-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;
-
-@State(Scope.Benchmark)
-@BenchmarkMode(Mode.AverageTime)
-@OutputTimeUnit(TimeUnit.NANOSECONDS)
-@Warmup(iterations = 5, time = 1)
-@Measurement(iterations = 5, time = 1)
-public class CompositeReadableBufferStringDecodeBenchmark {
-
- private static final String PAYLOAD =
- "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
- + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
- + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
- + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
- + "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
-
- private static final String PAYLOAD_CHUNK =
- "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
-
- private final CharsetDecoder charsetDecoder = StandardCharsets.UTF_8.newDecoder();
-
- private CompositeReadableBuffer singleArrayString;
- private CompositeReadableBuffer splitArrayString;
-
- private Blackhole blackhole;
-
- @Setup
- public void init(Blackhole blackhole) {
- this.blackhole = blackhole;
-
- byte[] payload = PAYLOAD.getBytes(StandardCharsets.UTF_8);
- singleArrayString = new CompositeReadableBuffer();
- singleArrayString.append(payload);
-
- splitArrayString = new CompositeReadableBuffer();
-
- byte[] payloadChunk = PAYLOAD_CHUNK.getBytes(StandardCharsets.UTF_8);
- for (int i = 0; i < 5; i++) {
- splitArrayString.append(Arrays.copyOf(payloadChunk, payloadChunk.length));
- }
- }
-
- @Benchmark
- public void decodeSingleArray() throws CharacterCodingException {
- charsetDecoder.reset();
- blackhole.consume(singleArrayString.readString(charsetDecoder));
- singleArrayString.rewind();
- }
-
- @Benchmark
- public void decodeMultiArray() throws CharacterCodingException {
- charsetDecoder.reset();
- blackhole.consume(splitArrayString.readString(charsetDecoder));
- singleArrayString.rewind();
- }
-
- public static void main(String[] args) throws RunnerException {
- runBenchmark(CompositeReadableBufferStringDecodeBenchmark.class);
- }
-
- public static void runBenchmark(Class<?> benchmarkClass) throws RunnerException {
- final Options opt = new OptionsBuilder()
- .include(benchmarkClass.getSimpleName())
- .addProfiler(GCProfiler.class)
- .shouldDoGC(true)
- .warmupIterations(5)
- .measurementIterations(5)
- .forks(1)
- .build();
- new Runner(opt).run();
- }
-}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org