Repository: qpid-proton-j Updated Branches: refs/heads/master 459b84d44 -> 243dd0dd7
PROTON-1965: Optimize CompositeReadableBuffer::equals for the single-array case. PR from Francesco Nigro with fixup from Robbie. This closes #20. 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/243dd0dd Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton-j/tree/243dd0dd Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton-j/diff/243dd0dd Branch: refs/heads/master Commit: 243dd0dd77f228300957ccec74c8fff27e9db3cd Parents: 459b84d Author: Francesco Nigro <nigro....@gmail.com> Authored: Tue Nov 20 11:58:31 2018 +0000 Committer: Robbie Gemmell <rob...@apache.org> Committed: Tue Nov 20 11:58:31 2018 +0000 ---------------------------------------------------------------------- .../proton/codec/CompositeReadableBuffer.java | 32 +++++-- .../codec/CompositeReadableBufferBenchmark.java | 88 ++++++++++++++++++++ 2 files changed, 113 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/243dd0dd/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 1441dcb..409b192 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 @@ -834,22 +834,40 @@ public class CompositeReadableBuffer implements ReadableBuffer { return false; } - ReadableBuffer buffer = (ReadableBuffer)other; - if (this.remaining() != buffer.remaining()) { + ReadableBuffer buffer = (ReadableBuffer) other; + final int remaining = remaining(); + if (remaining != buffer.remaining()) { return false; } - final int origPos = position(); + if (hasArray()) { + return equals(currentArray, currentOffset, remaining, buffer); + } else { + return equals(this, buffer); + } + } + + private static boolean equals(byte[] buffer, int start, int length, ReadableBuffer other) { + final int position = other.position(); + for (int i = 0; i < length; i++) { + if (buffer[start + i] != other.get(position + i)) { + return false; + } + } + return true; + } + + private static boolean equals(ReadableBuffer buffer, ReadableBuffer other) { + final int origPos = buffer.position(); try { - for (int i = buffer.position(); hasRemaining(); i++) { - if (!equals(this.get(), buffer.get(i))) { + for (int i = other.position(); buffer.hasRemaining(); i++) { + if (!equals(buffer.get(), other.get(i))) { return false; } } - return true; } finally { - position(origPos); + buffer.position(origPos); } } http://git-wip-us.apache.org/repos/asf/qpid-proton-j/blob/243dd0dd/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 new file mode 100644 index 0000000..4d58a68 --- /dev/null +++ b/tests/performance-jmh/src/main/java/org/apache/qpid/proton/codec/CompositeReadableBufferBenchmark.java @@ -0,0 +1,88 @@ +/** + * 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 org.apache.qpid.proton.codec.ReadableBuffer.ByteBufferReader; +import org.openjdk.jmh.annotations.*; +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) +@Warmup(iterations = 5, time = 1) +@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; + + @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); + } + } + + @Benchmark + public boolean equalsToByteBufferReader() { + composite.position(0); + return composite.equals(bufferReader); + } + + public static void main(String[] args) throws RunnerException { + runBenchmark(CompositeReadableBuffer.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-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org