From e6918187568dbd01842d8d1d2c808ce16a894239 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 21 Apr 2024 13:54:28 +0200 Subject: Adding upstream version 18.2.2. Signed-off-by: Daniel Baumann --- src/arrow/java/performance/pom.xml | 233 +++++++++++++ .../arrow/adapter/AvroAdapterBenchmarks.java | 141 ++++++++ .../arrow/adapter/jdbc/JdbcAdapterBenchmarks.java | 359 +++++++++++++++++++++ .../search/ParallelSearcherBenchmarks.java | 115 +++++++ .../apache/arrow/memory/AllocatorBenchmarks.java | 95 ++++++ .../apache/arrow/memory/ArrowBufBenchmarks.java | 82 +++++ .../memory/util/ArrowBufPointerBenchmarks.java | 107 ++++++ .../memory/util/ByteFunctionHelpersBenchmarks.java | 138 ++++++++ .../arrow/vector/BaseValueVectorBenchmarks.java | 95 ++++++ .../arrow/vector/BitVectorHelperBenchmarks.java | 229 +++++++++++++ .../arrow/vector/DecimalVectorBenchmarks.java | 121 +++++++ .../org/apache/arrow/vector/Float8Benchmarks.java | 122 +++++++ .../arrow/vector/FloatingPointBenchmarks.java | 134 ++++++++ .../org/apache/arrow/vector/IntBenchmarks.java | 110 +++++++ .../org/apache/arrow/vector/VarCharBenchmarks.java | 102 ++++++ .../vector/VariableWidthVectorBenchmarks.java | 130 ++++++++ .../apache/arrow/vector/VectorLoaderBenchmark.java | 117 +++++++ .../arrow/vector/VectorUnloaderBenchmark.java | 109 +++++++ .../dictionary/DictionaryEncoderBenchmarks.java | 147 +++++++++ .../arrow/vector/ipc/WriteChannelBenchmark.java | 87 +++++ .../ipc/message/ArrowRecordBatchBenchmarks.java | 98 ++++++ .../arrow/vector/util/TransferPairBenchmarks.java | 123 +++++++ 22 files changed, 2994 insertions(+) create mode 100644 src/arrow/java/performance/pom.xml create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/adapter/AvroAdapterBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/adapter/jdbc/JdbcAdapterBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/algorithm/search/ParallelSearcherBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/memory/AllocatorBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/memory/ArrowBufBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/memory/util/ArrowBufPointerBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/memory/util/ByteFunctionHelpersBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/vector/BaseValueVectorBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/vector/BitVectorHelperBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/vector/DecimalVectorBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/vector/Float8Benchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/vector/FloatingPointBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/vector/IntBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VarCharBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VariableWidthVectorBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VectorLoaderBenchmark.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VectorUnloaderBenchmark.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/vector/dictionary/DictionaryEncoderBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/vector/ipc/WriteChannelBenchmark.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/vector/ipc/message/ArrowRecordBatchBenchmarks.java create mode 100644 src/arrow/java/performance/src/test/java/org/apache/arrow/vector/util/TransferPairBenchmarks.java (limited to 'src/arrow/java/performance') diff --git a/src/arrow/java/performance/pom.xml b/src/arrow/java/performance/pom.xml new file mode 100644 index 000000000..c2be88c8a --- /dev/null +++ b/src/arrow/java/performance/pom.xml @@ -0,0 +1,233 @@ + + + + 4.0.0 + + arrow-java-root + org.apache.arrow + 6.0.1 + + arrow-performance + jar + Arrow Performance Benchmarks + JMH Performance benchmarks for other Arrow libraries. + + + + org.openjdk.jmh + jmh-core + ${jmh.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + provided + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.1 + runtime + + + org.apache.logging.log4j + log4j-core + 2.1 + runtime + + + org.apache.arrow + arrow-vector + ${project.version} + ${arrow.vector.classifier} + + + org.apache.arrow + arrow-memory-core + ${project.version} + + + org.apache.arrow + arrow-memory-netty + ${project.version} + test + + + org.apache.avro + avro + ${dep.avro.version} + + + org.apache.arrow + arrow-avro + ${project.version} + + + com.h2database + h2 + 1.4.196 + test + + + org.apache.arrow + arrow-jdbc + ${project.version} + + + org.apache.arrow + arrow-algorithm + 6.0.1 + test + + + + + UTF-8 + 1.21 + 1.8 + benchmarks + true + .* + 1 + + 5 + 5 + + jmh-result.json + json + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${javac.target} + ${javac.target} + ${javac.target} + + + + org.apache.maven.plugins + maven-shade-plugin + 2.2 + + + package + + shade + + + ${uberjar.name} + + + org.openjdk.jmh.Main + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + run-java-benchmarks + integration-test + + exec + + + + + ${skip.perf.benchmarks} + test + java + + -classpath + + org.openjdk.jmh.Main + ${benchmark.filter} + -f + ${benchmark.forks} + -jvmArgs + ${benchmark.jvmargs} + -wi + ${benchmark.warmups} + -i + ${benchmark.runs} + ${benchmark.list} + -rff + ${benchmark.resultfile} + -rf + ${benchmark.resultformat} + + + + + + + + maven-clean-plugin + 2.5 + + + maven-deploy-plugin + 2.8.1 + + + maven-install-plugin + 2.5.1 + + + maven-jar-plugin + 2.4 + + + maven-javadoc-plugin + 2.9.1 + + + maven-resources-plugin + 2.6 + + + maven-site-plugin + 3.3 + + + maven-source-plugin + 2.2.1 + + + maven-surefire-plugin + 3.0.0-M3 + + + + + + diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/adapter/AvroAdapterBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/adapter/AvroAdapterBenchmarks.java new file mode 100644 index 000000000..884647b5a --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/adapter/AvroAdapterBenchmarks.java @@ -0,0 +1,141 @@ +/* + * 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.arrow.adapter; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.AvroToArrow; +import org.apache.arrow.AvroToArrowConfig; +import org.apache.arrow.AvroToArrowConfigBuilder; +import org.apache.arrow.AvroToArrowVectorIterator; +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.IntVector; +import org.apache.arrow.vector.VectorSchemaRoot; +import org.apache.avro.Schema; +import org.apache.avro.generic.GenericData; +import org.apache.avro.generic.GenericDatumWriter; +import org.apache.avro.generic.GenericRecord; +import org.apache.avro.io.BinaryDecoder; +import org.apache.avro.io.BinaryEncoder; +import org.apache.avro.io.DatumWriter; +import org.apache.avro.io.Decoder; +import org.apache.avro.io.DecoderFactory; +import org.apache.avro.io.EncoderFactory; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +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; + +/** + * Benchmarks for avro adapter. + */ +@State(Scope.Benchmark) +public class AvroAdapterBenchmarks { + + private final int valueCount = 3000; + + private AvroToArrowConfig config; + + private Schema schema; + private BinaryDecoder decoder; + + /** + * Setup benchmarks. + */ + @Setup + public void prepare() throws Exception { + BufferAllocator allocator = new RootAllocator(Integer.MAX_VALUE); + config = new AvroToArrowConfigBuilder(allocator).build(); + + String schemaStr = "{\n" + " \"namespace\": \"org.apache.arrow.avro\",\n" + + " \"type\": \"record\",\n" + " \"name\": \"testBenchmark\",\n" + " \"fields\": [\n" + + " {\"name\": \"f0\", \"type\": \"string\"},\n" + + " {\"name\": \"f1\", \"type\": \"int\"},\n" + + " {\"name\": \"f2\", \"type\": \"long\"},\n" + + " {\"name\": \"f3\", \"type\": \"boolean\"},\n" + + " {\"name\": \"f4\", \"type\": \"float\"}\n" + " ]\n" + "}"; + schema = new Schema.Parser().parse(schemaStr); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + BinaryEncoder encoder = new EncoderFactory().directBinaryEncoder(out, null); + DatumWriter writer = new GenericDatumWriter(schema); + + for (int i = 0; i < valueCount; i++) { + GenericRecord record = new GenericData.Record(schema); + record.put(0, "test" + i); + record.put(1, i); + record.put(2, i + 1L); + record.put(3, i % 2 == 0); + record.put(4, i + 0.1f); + writer.write(record, encoder); + } + + decoder = new DecoderFactory().directBinaryDecoder(new ByteArrayInputStream(out.toByteArray()), null); + } + + /** + * Tear down benchmarks. + */ + @TearDown + public void tearDown() { + config.getAllocator().close(); + } + + /** + * Test {@link AvroToArrow#avroToArrowIterator(Schema, Decoder, AvroToArrowConfig)}. + * @return useless. To avoid DCE by JIT. + */ + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public int testAvroToArrow() throws Exception { + decoder.inputStream().reset(); + int sum = 0; + try (AvroToArrowVectorIterator iter = AvroToArrow.avroToArrowIterator(schema, decoder, config)) { + while (iter.hasNext()) { + VectorSchemaRoot root = iter.next(); + IntVector intVector = (IntVector) root.getVector("f1"); + for (int i = 0; i < intVector.getValueCount(); i++) { + sum += intVector.get(i); + } + root.close(); + } + } + return sum; + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(AvroAdapterBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/adapter/jdbc/JdbcAdapterBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/adapter/jdbc/JdbcAdapterBenchmarks.java new file mode 100644 index 000000000..fd3940b4c --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/adapter/jdbc/JdbcAdapterBenchmarks.java @@ -0,0 +1,359 @@ +/* + * 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.arrow.adapter.jdbc; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.Statement; +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.adapter.jdbc.consumer.BigIntConsumer; +import org.apache.arrow.adapter.jdbc.consumer.BitConsumer; +import org.apache.arrow.adapter.jdbc.consumer.IntConsumer; +import org.apache.arrow.adapter.jdbc.consumer.JdbcConsumer; +import org.apache.arrow.adapter.jdbc.consumer.VarCharConsumer; +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.BigIntVector; +import org.apache.arrow.vector.BitVector; +import org.apache.arrow.vector.IntVector; +import org.apache.arrow.vector.VarCharVector; +import org.apache.arrow.vector.VectorSchemaRoot; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Level; +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.TearDown; +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; + +/** + * Benchmarks for Jdbc adapter. + */ +public class JdbcAdapterBenchmarks { + + private static final int VALUE_COUNT = 3000; + + private static final String CREATE_STATEMENT = + "CREATE TABLE test_table (f0 INT, f1 LONG, f2 VARCHAR, f3 BOOLEAN);"; + private static final String INSERT_STATEMENT = + "INSERT INTO test_table (f0, f1, f2, f3) VALUES (?, ?, ?, ?);"; + private static final String QUERY = "SELECT f0, f1, f2, f3 FROM test_table;"; + private static final String DROP_STATEMENT = "DROP TABLE test_table;"; + + private static final String URL = "jdbc:h2:mem:JdbcAdapterBenchmarks"; + private static final String DRIVER = "org.h2.Driver"; + + /** + * State object for the jdbc e2e benchmark. + */ + @State(Scope.Benchmark) + public static class JdbcState { + + private Connection conn = null; + + private ResultSet resultSet = null; + + private BufferAllocator allocator; + + private Statement statement; + + private JdbcToArrowConfig config; + + @Setup(Level.Trial) + public void prepareState() throws Exception { + allocator = new RootAllocator(Integer.MAX_VALUE); + config = new JdbcToArrowConfigBuilder().setAllocator(allocator).setTargetBatchSize(1024).build(); + Class.forName(DRIVER); + conn = DriverManager.getConnection(URL); + + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate(CREATE_STATEMENT); + } + + for (int i = 0; i < VALUE_COUNT; i++) { + // Insert data + try (PreparedStatement stmt = conn.prepareStatement(INSERT_STATEMENT)) { + + stmt.setInt(1, i); + stmt.setLong(2, i); + stmt.setString(3, "test" + i); + stmt.setBoolean(4, i % 2 == 0); + stmt.executeUpdate(); + } + } + } + + @Setup(Level.Invocation) + public void prepareInvoke() throws Exception { + statement = conn.createStatement(); + resultSet = statement.executeQuery(QUERY); + } + + @TearDown(Level.Invocation) + public void tearDownInvoke() throws Exception { + resultSet.close(); + statement.close(); + } + + @TearDown(Level.Trial) + public void tearDownState() throws Exception { + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate(DROP_STATEMENT); + } + allocator.close(); + } + } + + /** + * State object for the consume benchmark. + */ + @State(Scope.Benchmark) + public static class ConsumeState { + + private static final boolean NULLABLE = true; + + private Connection conn = null; + + private ResultSet resultSet = null; + + private BufferAllocator allocator; + + private Statement statement; + + private IntVector intVector; + + private BigIntVector longVector; + + private VarCharVector varCharVector; + + private BitVector bitVector; + + private JdbcConsumer intConsumer; + + private JdbcConsumer longConsumer; + + private JdbcConsumer varCharConsumer; + + private JdbcConsumer bitConsumer; + + private JdbcToArrowConfig config; + + @Setup(Level.Trial) + public void prepare() throws Exception { + allocator = new RootAllocator(Integer.MAX_VALUE); + config = new JdbcToArrowConfigBuilder().setAllocator(allocator).setTargetBatchSize(1024).build(); + + Class.forName(DRIVER); + conn = DriverManager.getConnection(URL); + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate(CREATE_STATEMENT); + } + + for (int i = 0; i < VALUE_COUNT; i++) { + // Insert data + try (PreparedStatement stmt = conn.prepareStatement(INSERT_STATEMENT)) { + + stmt.setInt(1, i); + stmt.setLong(2, i); + stmt.setString(3, "test" + i); + stmt.setBoolean(4, i % 2 == 0); + stmt.executeUpdate(); + } + } + + statement = conn.createStatement(); + resultSet = statement.executeQuery(QUERY); + resultSet.next(); + + intVector = new IntVector("", allocator); + intVector.allocateNew(VALUE_COUNT); + intConsumer = IntConsumer.createConsumer(intVector, 1, NULLABLE); + + longVector = new BigIntVector("", allocator); + longVector.allocateNew(VALUE_COUNT); + longConsumer = BigIntConsumer.createConsumer(longVector, 2, NULLABLE); + + varCharVector = new VarCharVector("", allocator); + varCharVector.allocateNew(VALUE_COUNT); + varCharConsumer = VarCharConsumer.createConsumer(varCharVector, 3, NULLABLE); + + bitVector = new BitVector("", allocator); + bitVector.allocateNew(VALUE_COUNT); + bitConsumer = BitConsumer.createConsumer(bitVector, 4, NULLABLE); + } + + @TearDown(Level.Trial) + public void tearDown() throws Exception { + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate(DROP_STATEMENT); + } + + resultSet.close(); + statement.close(); + conn.close(); + + intVector.close(); + intConsumer.close(); + + longVector.close(); + longConsumer.close(); + + varCharVector.close(); + varCharConsumer.close(); + + bitVector.close(); + bitConsumer.close(); + + allocator.close(); + } + } + + /** + * State object for the jdbc row consume benchmark. + */ + @State(Scope.Benchmark) + public static class RowConsumeState { + + private Connection conn = null; + + private ResultSet resultSet = null; + + private BufferAllocator allocator; + + private Statement statement; + + private JdbcToArrowConfig config; + + private ArrowVectorIterator iter; + + private VectorSchemaRoot root; + + @Setup(Level.Trial) + public void prepareState() throws Exception { + allocator = new RootAllocator(Integer.MAX_VALUE); + config = new JdbcToArrowConfigBuilder().setAllocator(allocator).setTargetBatchSize(VALUE_COUNT).build(); + Class.forName(DRIVER); + conn = DriverManager.getConnection(URL); + + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate(CREATE_STATEMENT); + } + + for (int i = 0; i < VALUE_COUNT; i++) { + // Insert data + try (PreparedStatement stmt = conn.prepareStatement(INSERT_STATEMENT)) { + + stmt.setInt(1, i); + stmt.setLong(2, i); + stmt.setString(3, "test" + i); + stmt.setBoolean(4, i % 2 == 0); + stmt.executeUpdate(); + } + } + } + + @Setup(Level.Invocation) + public void prepareInvoke() throws Exception { + statement = conn.createStatement(); + resultSet = statement.executeQuery(QUERY); + + iter = JdbcToArrow.sqlToArrowVectorIterator(resultSet, config); + root = iter.next(); + iter.compositeConsumer.resetVectorSchemaRoot(root); + } + + @TearDown(Level.Invocation) + public void tearDownInvoke() throws Exception { + resultSet.close(); + statement.close(); + iter.close(); + } + + @TearDown(Level.Trial) + public void tearDownState() throws Exception { + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate(DROP_STATEMENT); + } + allocator.close(); + } + } + + /** + * Test {@link JdbcToArrow#sqlToArrowVectorIterator(ResultSet, JdbcToArrowConfig)}. + * @return useless. To avoid DCE by JIT. + */ + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public int testJdbcToArrow(JdbcState state) throws Exception { + int valueCount = 0; + try (ArrowVectorIterator iter = JdbcToArrow.sqlToArrowVectorIterator(state.resultSet, state.config)) { + while (iter.hasNext()) { + VectorSchemaRoot root = iter.next(); + IntVector intVector = (IntVector) root.getFieldVectors().get(0); + valueCount += intVector.getValueCount(); + root.close(); + } + } + return valueCount; + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void consumeBenchmark(ConsumeState state) throws Exception { + state.intConsumer.resetValueVector(state.intVector); + state.longConsumer.resetValueVector(state.longVector); + state.varCharConsumer.resetValueVector(state.varCharVector); + state.bitConsumer.resetValueVector(state.bitVector); + for (int i = 0; i < VALUE_COUNT; i++) { + state.intConsumer.consume(state.resultSet); + state.longConsumer.consume(state.resultSet); + state.varCharConsumer.consume(state.resultSet); + state.bitConsumer.consume(state.resultSet); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void consumeRowsBenchmark(RowConsumeState state) throws Exception { + for (int i = 0; i < VALUE_COUNT; i++) { + state.iter.compositeConsumer.consume(state.resultSet); + } + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(JdbcAdapterBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} + diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/algorithm/search/ParallelSearcherBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/algorithm/search/ParallelSearcherBenchmarks.java new file mode 100644 index 000000000..1c3af77e7 --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/algorithm/search/ParallelSearcherBenchmarks.java @@ -0,0 +1,115 @@ +/* + * 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.arrow.algorithm.search; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.IntVector; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Level; +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.TearDown; +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; + +/** + * Benchmarks for {@link ParallelSearcher}. + */ +public class ParallelSearcherBenchmarks { + + private static final int VECTOR_LENGTH = 1024 * 1024; + + /** + * State object for the benchmarks. + */ + @State(Scope.Benchmark) + public static class SearchState { + + @Param({"1", "2", "5", "10", "20", "50", "100"}) + int numThreads; + + BufferAllocator allocator; + + ExecutorService threadPool; + + IntVector targetVector; + + IntVector keyVector; + + ParallelSearcher searcher; + + @Setup(Level.Trial) + public void prepare() { + allocator = new RootAllocator(Integer.MAX_VALUE); + targetVector = new IntVector("target vector", allocator); + targetVector.allocateNew(VECTOR_LENGTH); + keyVector = new IntVector("key vector", allocator); + keyVector.allocateNew(1); + threadPool = Executors.newFixedThreadPool(numThreads); + + for (int i = 0; i < VECTOR_LENGTH; i++) { + targetVector.set(i, i); + } + targetVector.setValueCount(VECTOR_LENGTH); + + keyVector.set(0, VECTOR_LENGTH / 3); + keyVector.setValueCount(1); + } + + @Setup(Level.Invocation) + public void prepareInvoke() { + searcher = new ParallelSearcher<>(targetVector, threadPool, numThreads); + } + + @TearDown(Level.Trial) + public void tearDownState() { + targetVector.close(); + keyVector.close(); + allocator.close(); + threadPool.shutdown(); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void searchBenchmark(SearchState state) throws Exception { + state.searcher.search(state.keyVector, 0); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(ParallelSearcherBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/memory/AllocatorBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/memory/AllocatorBenchmarks.java new file mode 100644 index 000000000..88fcf73f0 --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/memory/AllocatorBenchmarks.java @@ -0,0 +1,95 @@ +/* + * 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.arrow.memory; + +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.ArrowBuf; +import org.apache.arrow.memory.rounding.RoundingPolicy; +import org.apache.arrow.memory.rounding.SegmentRoundingPolicy; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +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; + +/** + * Benchmarks for allocators. + */ +public class AllocatorBenchmarks { + + /** + * Benchmark for the default allocator. + */ + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void defaultAllocatorBenchmark() { + final int bufferSize = 1024; + final int numBuffers = 1024; + + try (RootAllocator allocator = new RootAllocator(numBuffers * bufferSize)) { + ArrowBuf[] buffers = new ArrowBuf[numBuffers]; + + for (int i = 0; i < numBuffers; i++) { + buffers[i] = allocator.buffer(bufferSize); + } + + for (int i = 0; i < numBuffers; i++) { + buffers[i].close(); + } + } + } + + /** + * Benchmark for allocator with segment rounding policy. + */ + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void segmentRoundingPolicyBenchmark() { + final int bufferSize = 1024; + final int numBuffers = 1024; + final int segmentSize = 1024; + + RoundingPolicy policy = new SegmentRoundingPolicy(segmentSize); + try (RootAllocator allocator = new RootAllocator(AllocationListener.NOOP, bufferSize * numBuffers, policy)) { + ArrowBuf[] buffers = new ArrowBuf[numBuffers]; + + for (int i = 0; i < numBuffers; i++) { + buffers[i] = allocator.buffer(bufferSize); + } + + for (int i = 0; i < numBuffers; i++) { + buffers[i].close(); + } + } + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(AllocatorBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/memory/ArrowBufBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/memory/ArrowBufBenchmarks.java new file mode 100644 index 000000000..ef4da5828 --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/memory/ArrowBufBenchmarks.java @@ -0,0 +1,82 @@ +/* + * 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.arrow.memory; + +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +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; + +/** + * Benchmarks for {@link ArrowBuf}. + */ +@State(Scope.Benchmark) +public class ArrowBufBenchmarks { + + private static final int BUFFER_CAPACITY = 1024 * 1024; + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private BufferAllocator allocator; + + private ArrowBuf buffer; + + /** + * Setup benchmarks. + */ + @Setup + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + buffer = allocator.buffer(BUFFER_CAPACITY); + } + + /** + * Tear down benchmarks. + */ + @TearDown + public void tearDown() { + buffer.close(); + allocator.close(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void setZero() { + buffer.setZero(0, BUFFER_CAPACITY); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(ArrowBufBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/memory/util/ArrowBufPointerBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/memory/util/ArrowBufPointerBenchmarks.java new file mode 100644 index 000000000..8e2c9cc51 --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/memory/util/ArrowBufPointerBenchmarks.java @@ -0,0 +1,107 @@ +/* + * 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.arrow.memory.util; + +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.ArrowBuf; +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +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; + +/** + * Benchmarks for {@link ArrowBufPointer}. + */ +@State(Scope.Benchmark) +public class ArrowBufPointerBenchmarks { + + private static final int BUFFER_CAPACITY = 1000; + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private BufferAllocator allocator; + + private ArrowBuf buffer1; + + private ArrowBuf buffer2; + + private ArrowBufPointer pointer1; + + private ArrowBufPointer pointer2; + + /** + * Setup benchmarks. + */ + @Setup + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + buffer1 = allocator.buffer(BUFFER_CAPACITY); + buffer2 = allocator.buffer(BUFFER_CAPACITY); + + for (int i = 0; i < BUFFER_CAPACITY; i++) { + buffer1.setByte(i, i); + buffer2.setByte(i, i); + } + + // make the last bytes different + buffer1.setByte(BUFFER_CAPACITY - 1, 12); + buffer1.setByte(BUFFER_CAPACITY - 1, 123); + + pointer1 = new ArrowBufPointer(buffer1, 0, BUFFER_CAPACITY); + pointer2 = new ArrowBufPointer(buffer2, 0, BUFFER_CAPACITY); + } + + /** + * Tear down benchmarks. + */ + @TearDown + public void tearDown() { + buffer1.close(); + buffer2.close(); + allocator.close(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public int compareBenchmark() { + return pointer1.compareTo(pointer2); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(ArrowBufPointerBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} + + diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/memory/util/ByteFunctionHelpersBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/memory/util/ByteFunctionHelpersBenchmarks.java new file mode 100644 index 000000000..4d0dfcb5d --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/memory/util/ByteFunctionHelpersBenchmarks.java @@ -0,0 +1,138 @@ +/* + * 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.arrow.memory.util; + +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.ArrowBuf; +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Level; +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.TearDown; +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; + +/** + * Benchmarks for {@link ByteFunctionHelpers}. + */ +public class ByteFunctionHelpersBenchmarks { + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + /** + * State object for the {@link ByteFunctionHelpersBenchmarks#arrowBufEquals(ArrowEqualState)} benchmark. + */ + @State(Scope.Benchmark) + public static class ArrowEqualState { + + private static final int BUFFER_CAPACITY = 7; + + private BufferAllocator allocator; + + private ArrowBuf buffer1; + + private ArrowBuf buffer2; + + @Setup(Level.Trial) + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + buffer1 = allocator.buffer(BUFFER_CAPACITY); + buffer2 = allocator.buffer(BUFFER_CAPACITY); + + for (int i = 0; i < BUFFER_CAPACITY; i++) { + buffer1.setByte(i, i); + buffer2.setByte(i, i); + } + } + + @TearDown(Level.Trial) + public void tearDown() { + buffer1.close(); + buffer2.close(); + allocator.close(); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void arrowBufEquals(ArrowEqualState state) { + ByteFunctionHelpers.equal(state.buffer1, 0, ArrowEqualState.BUFFER_CAPACITY - 1, + state.buffer2, 0, ArrowEqualState.BUFFER_CAPACITY - 1); + } + + /** + * State object for the {@link ByteFunctionHelpersBenchmarks#arrowBufArrayEquals(ArrowArrayEqualState)} benchmark. + */ + @State(Scope.Benchmark) + public static class ArrowArrayEqualState { + + private static final int BUFFER_CAPACITY = 1024; + + private BufferAllocator allocator; + + private ArrowBuf buffer1; + + private byte[] buffer2; + + @Setup(Level.Trial) + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + buffer1 = allocator.buffer(BUFFER_CAPACITY); + buffer2 = new byte[BUFFER_CAPACITY]; + + for (int i = 0; i < BUFFER_CAPACITY; i++) { + buffer1.setByte(i, i); + buffer2[i] = (byte) i; + } + } + + @TearDown(Level.Trial) + public void tearDown() { + buffer1.close(); + allocator.close(); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public int arrowBufArrayEquals(ArrowArrayEqualState state) { + return ByteFunctionHelpers.compare( + state.buffer1, 0, ArrowArrayEqualState.BUFFER_CAPACITY, + state.buffer2, 0, ArrowArrayEqualState.BUFFER_CAPACITY); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(ByteFunctionHelpersBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/BaseValueVectorBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/BaseValueVectorBenchmarks.java new file mode 100644 index 000000000..5d6441cd5 --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/BaseValueVectorBenchmarks.java @@ -0,0 +1,95 @@ +/* + * 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.arrow.vector; + +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +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; + +/** + * Benchmarks for {@link BaseValueVector}. + */ +@State(Scope.Benchmark) +public class BaseValueVectorBenchmarks { + + private static final int VECTOR_LENGTH = 1024; + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private BufferAllocator allocator; + + private IntVector vector; + + /** + * Setup benchmarks. + */ + @Setup + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + vector = new IntVector("vector", allocator); + vector.allocateNew(VECTOR_LENGTH); + } + + /** + * Tear down benchmarks. + */ + @TearDown + public void tearDown() { + vector.close(); + allocator.close(); + } + + /** + * Test {@link BaseValueVector#computeCombinedBufferSize(int, int)}. + * @return useless. To avoid DCE by JIT. + */ + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public int testComputeCombinedBufferSize() { + int totalSize = 0; + for (int i = 0; i < VECTOR_LENGTH; i++) { + totalSize += vector.computeCombinedBufferSize(i, 4); + } + return totalSize; + } + + public static void main(String [] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(BaseValueVectorBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } + + +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/BitVectorHelperBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/BitVectorHelperBenchmarks.java new file mode 100644 index 000000000..5f6e5ca28 --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/BitVectorHelperBenchmarks.java @@ -0,0 +1,229 @@ +/* + * 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.arrow.vector; + +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.ArrowBuf; +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.ipc.message.ArrowFieldNode; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Level; +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.TearDown; +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; + +/** + * Benchmarks for {@link BitVectorHelper}. + */ +public class BitVectorHelperBenchmarks { + + /** + * State object for general benchmarks. + */ + @State(Scope.Benchmark) + public static class BenchmarkState { + + private static final int VALIDITY_BUFFER_CAPACITY = 1024; + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private BufferAllocator allocator; + + private ArrowBuf validityBuffer; + + private ArrowBuf oneBitValidityBuffer; + + /** + * Setup benchmarks. + */ + @Setup(Level.Trial) + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + validityBuffer = allocator.buffer(VALIDITY_BUFFER_CAPACITY / 8); + + for (int i = 0; i < VALIDITY_BUFFER_CAPACITY; i++) { + if (i % 7 == 0) { + BitVectorHelper.setBit(validityBuffer, i); + } else { + BitVectorHelper.unsetBit(validityBuffer, i); + } + } + + // only one 1 bit in the middle of the buffer + oneBitValidityBuffer = allocator.buffer(VALIDITY_BUFFER_CAPACITY / 8); + oneBitValidityBuffer.setZero(0, VALIDITY_BUFFER_CAPACITY / 8); + BitVectorHelper.setBit(oneBitValidityBuffer, VALIDITY_BUFFER_CAPACITY / 2); + } + + /** + * Tear down benchmarks. + */ + @TearDown(Level.Trial) + public void tearDown() { + validityBuffer.close(); + oneBitValidityBuffer.close(); + allocator.close(); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public int getNullCountBenchmark(BenchmarkState state) { + return BitVectorHelper.getNullCount(state.validityBuffer, BenchmarkState.VALIDITY_BUFFER_CAPACITY); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public boolean allBitsNullBenchmark(BenchmarkState state) { + return BitVectorHelper.checkAllBitsEqualTo( + state.oneBitValidityBuffer, BenchmarkState.VALIDITY_BUFFER_CAPACITY, true); + } + + /** + * State object for {@link #loadValidityBufferAllOne(NonNullableValidityBufferState)}.. + */ + @State(Scope.Benchmark) + public static class NonNullableValidityBufferState { + + private static final int VALIDITY_BUFFER_CAPACITY = 1024; + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private BufferAllocator allocator; + + private ArrowBuf validityBuffer; + + private ArrowBuf loadResult; + + private ArrowFieldNode fieldNode; + + /** + * Setup benchmarks. + */ + @Setup(Level.Trial) + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + validityBuffer = allocator.buffer(VALIDITY_BUFFER_CAPACITY / 8); + + for (int i = 0; i < VALIDITY_BUFFER_CAPACITY; i++) { + BitVectorHelper.setBit(validityBuffer, i); + } + + fieldNode = new ArrowFieldNode(VALIDITY_BUFFER_CAPACITY, 0); + } + + @TearDown(Level.Invocation) + public void tearDownInvoke() { + loadResult.close(); + } + + /** + * Tear down benchmarks. + */ + @TearDown(Level.Trial) + public void tearDown() { + validityBuffer.close(); + allocator.close(); + } + } + + /** + * Benchmark for {@link BitVectorHelper#loadValidityBuffer(ArrowFieldNode, ArrowBuf, BufferAllocator)} + * when all elements are not null. + */ + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void loadValidityBufferAllOne(NonNullableValidityBufferState state) { + state.loadResult = BitVectorHelper.loadValidityBuffer(state.fieldNode, state.validityBuffer, state.allocator); + } + + /** + * State object for {@link #setValidityBitBenchmark(ClearBitStateState)}. + */ + @State(Scope.Benchmark) + public static class ClearBitStateState { + + private static final int VALIDITY_BUFFER_CAPACITY = 1024; + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private BufferAllocator allocator; + + private ArrowBuf validityBuffer; + + private int bitToSet = 0; + + /** + * Setup benchmarks. + */ + @Setup(Level.Trial) + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + validityBuffer = allocator.buffer(VALIDITY_BUFFER_CAPACITY / 8); + } + + /** + * Tear down benchmarks. + */ + @TearDown(Level.Trial) + public void tearDown() { + validityBuffer.close(); + allocator.close(); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void setValidityBitBenchmark(ClearBitStateState state) { + for (int i = 0; i < ClearBitStateState.VALIDITY_BUFFER_CAPACITY; i++) { + BitVectorHelper.setValidityBit(state.validityBuffer, i, state.bitToSet); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void setValidityBitToZeroBenchmark(ClearBitStateState state) { + for (int i = 0; i < ClearBitStateState.VALIDITY_BUFFER_CAPACITY; i++) { + BitVectorHelper.unsetBit(state.validityBuffer, i); + } + } + + public static void main(String [] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(BitVectorHelperBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/DecimalVectorBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/DecimalVectorBenchmarks.java new file mode 100644 index 000000000..72f565990 --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/DecimalVectorBenchmarks.java @@ -0,0 +1,121 @@ +/* + * 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.arrow.vector; + +import java.math.BigDecimal; +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.ArrowBuf; +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +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; + +/** + * Benchmarks for {@link DecimalVector}. + */ +@State(Scope.Benchmark) +public class DecimalVectorBenchmarks { + + private static final int VECTOR_LENGTH = 1024; + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private BufferAllocator allocator; + + private DecimalVector vector; + + private ArrowBuf fromBuf; + + byte[] fromByteArray; + + /** + * Setup benchmarks. + */ + @Setup + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + vector = new DecimalVector("vector", allocator, 38, 16); + vector.allocateNew(VECTOR_LENGTH); + + fromBuf = allocator.buffer(VECTOR_LENGTH * DecimalVector.TYPE_WIDTH); + for (int i = 0; i < VECTOR_LENGTH; i++) { + byte[] bytes = BigDecimal.valueOf(i).unscaledValue().toByteArray(); + fromBuf.setBytes(i * DecimalVector.TYPE_WIDTH, bytes); + } + + fromByteArray = new byte[DecimalVector.TYPE_WIDTH]; + fromBuf.getBytes(0, fromByteArray); + } + + /** + * Tear down benchmarks. + */ + @TearDown + public void tearDown() { + fromBuf.close(); + vector.close(); + allocator.close(); + } + + /** + * Test writing on {@link DecimalVector} from arrow buf. + */ + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void setBigEndianArrowBufBenchmark() { + int offset = 0; + + for (int i = 0; i < VECTOR_LENGTH; i++) { + vector.setBigEndianSafe(i, offset, fromBuf, DecimalVector.TYPE_WIDTH); + offset += 8; + } + } + + /** + * Test writing on {@link DecimalVector} from byte array. + */ + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void setBigEndianByteArrayBenchmark() { + for (int i = 0; i < VECTOR_LENGTH; i++) { + vector.setBigEndian(i, fromByteArray); + } + } + + public static void main(String [] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(DecimalVectorBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/Float8Benchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/Float8Benchmarks.java new file mode 100644 index 000000000..874e0d9f8 --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/Float8Benchmarks.java @@ -0,0 +1,122 @@ +/* + * 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.arrow.vector; + +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.BoundsChecking; +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +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; + +/** + * Benchmarks for {@link Float8Vector}. + */ +@State(Scope.Benchmark) +public class Float8Benchmarks { + + private static final int VECTOR_LENGTH = 1024; + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private BufferAllocator allocator; + + private Float8Vector vector; + + private Float8Vector fromVector; + + /** + * Setup benchmarks. + */ + @Setup + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + vector = new Float8Vector("vector", allocator); + vector.allocateNew(VECTOR_LENGTH); + + fromVector = new Float8Vector("vector", allocator); + fromVector.allocateNew(VECTOR_LENGTH); + + for (int i = 0; i < VECTOR_LENGTH; i++) { + if (i % 3 == 0) { + fromVector.setNull(i); + } else { + fromVector.set(i, i * i); + } + } + fromVector.setValueCount(VECTOR_LENGTH); + } + + /** + * Tear down benchmarks. + */ + @TearDown + public void tearDown() { + vector.close(); + fromVector.close(); + allocator.close(); + } + + /** + * Test reading/writing on {@link Float8Vector}. + * The performance of this benchmark is influenced by the states of two flags: + * 1. The flag for boundary checking. For details, please see {@link BoundsChecking}. + * 2. The flag for null checking in get methods. For details, please see {@link NullCheckingForGet}. + * @return useless. To avoid DCE by JIT. + */ + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public double readWriteBenchmark() { + double sum = 0; + for (int i = 0; i < VECTOR_LENGTH; i++) { + vector.set(i, i + 10.0); + sum += vector.get(i); + } + return sum; + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void copyFromBenchmark() { + for (int i = 0; i < VECTOR_LENGTH; i++) { + vector.copyFrom(i, i, (Float8Vector) fromVector); + } + } + + public static void main(String [] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(Float8Benchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/FloatingPointBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/FloatingPointBenchmarks.java new file mode 100644 index 000000000..079672e9f --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/FloatingPointBenchmarks.java @@ -0,0 +1,134 @@ +/* + * 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.arrow.vector; + +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.compare.ApproxEqualsVisitor; +import org.apache.arrow.vector.compare.Range; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +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; + +/** + * Benchmarks for floating point vectors. + */ +@State(Scope.Benchmark) +public class FloatingPointBenchmarks { + + private static final int VECTOR_LENGTH = 1024; + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private BufferAllocator allocator; + + private Float4Vector floatVector1; + + private Float4Vector floatVector2; + + private Float8Vector doubleVector1; + + private Float8Vector doubleVector2; + + private ApproxEqualsVisitor floatVisitor; + + private ApproxEqualsVisitor doubleVisitor; + + private Range range; + + /** + * Setup benchmarks. + */ + @Setup + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + floatVector1 = new Float4Vector("vector", allocator); + floatVector2 = new Float4Vector("vector", allocator); + doubleVector1 = new Float8Vector("vector", allocator); + doubleVector2 = new Float8Vector("vector", allocator); + + floatVector1.allocateNew(VECTOR_LENGTH); + floatVector2.allocateNew(VECTOR_LENGTH); + doubleVector1.allocateNew(VECTOR_LENGTH); + doubleVector2.allocateNew(VECTOR_LENGTH); + + for (int i = 0; i < VECTOR_LENGTH; i++) { + if (i % 3 == 0) { + floatVector1.setNull(i); + floatVector2.setNull(i); + doubleVector1.setNull(i); + doubleVector2.setNull(i); + } else { + floatVector1.set(i, i * i); + floatVector2.set(i, i * i); + doubleVector1.set(i, i * i); + doubleVector2.set(i, i * i); + } + } + floatVector1.setValueCount(VECTOR_LENGTH); + floatVector2.setValueCount(VECTOR_LENGTH); + doubleVector1.setValueCount(VECTOR_LENGTH); + doubleVector2.setValueCount(VECTOR_LENGTH); + + floatVisitor = new ApproxEqualsVisitor(floatVector1, floatVector2, 0.01f, 0.01); + doubleVisitor = new ApproxEqualsVisitor(doubleVector1, doubleVector2, 0.01f, 0.01); + range = new Range(0, 0, VECTOR_LENGTH); + } + + /** + * Tear down benchmarks. + */ + @TearDown + public void tearDown() { + floatVector1.close(); + floatVector2.close(); + doubleVector1.close(); + doubleVector2.close(); + allocator.close(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public int approxEqualsBenchmark() { + boolean floatResult = floatVisitor.visit(floatVector1, range); + boolean doubleResult = doubleVisitor.visit(doubleVector1, range); + return (floatResult ? 1 : 0) + (doubleResult ? 1 : 0); + } + + public static void main(String [] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(FloatingPointBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} + diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/IntBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/IntBenchmarks.java new file mode 100644 index 000000000..036768d44 --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/IntBenchmarks.java @@ -0,0 +1,110 @@ +/* + * 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.arrow.vector; + +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.complex.impl.IntWriterImpl; +import org.apache.arrow.vector.holders.NullableIntHolder; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +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; + +/** + * Benchmarks for {@link IntVector}. + */ +@State(Scope.Benchmark) +public class IntBenchmarks { + + private static final int VECTOR_LENGTH = 1024; + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private BufferAllocator allocator; + + private IntVector vector; + + @Setup + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + vector = new IntVector("vector", allocator); + vector.allocateNew(VECTOR_LENGTH); + vector.setValueCount(VECTOR_LENGTH); + } + + @TearDown + public void tearDown() { + vector.close(); + allocator.close(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void setWithValueHolder() { + for (int i = 0; i < VECTOR_LENGTH; i++) { + NullableIntHolder holder = new NullableIntHolder(); + holder.isSet = i % 3 == 0 ? 0 : 1; + if (holder.isSet == 1) { + holder.value = i; + } + vector.setSafe(i, holder); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void setIntDirectly() { + for (int i = 0; i < VECTOR_LENGTH; i++) { + vector.setSafe(i, i % 3 == 0 ? 0 : 1, i); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void setWithWriter() { + IntWriterImpl writer = new IntWriterImpl(vector); + for (int i = 0; i < VECTOR_LENGTH; i++) { + if (i % 3 != 0) { + writer.writeInt(i); + } + } + } + + public static void main(String [] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(IntBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VarCharBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VarCharBenchmarks.java new file mode 100644 index 000000000..1ab4b7bc2 --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VarCharBenchmarks.java @@ -0,0 +1,102 @@ +/* + * 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.arrow.vector; + +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +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; + +/** + * Benchmarks for {@link VarCharVector}. + */ +@State(Scope.Benchmark) +public class VarCharBenchmarks { + + private static final int VECTOR_LENGTH = 1024; + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private BufferAllocator allocator; + + private VarCharVector vector; + + private VarCharVector fromVector; + + /** + * Setup benchmarks. + */ + @Setup + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + vector = new VarCharVector("vector", allocator); + vector.allocateNew(ALLOCATOR_CAPACITY / 4, VECTOR_LENGTH); + + fromVector = new VarCharVector("vector", allocator); + fromVector.allocateNew(ALLOCATOR_CAPACITY / 4, VECTOR_LENGTH); + + for (int i = 0; i < VECTOR_LENGTH; i++) { + if (i % 3 == 0) { + fromVector.setNull(i); + } else { + fromVector.set(i, String.valueOf(i * 1000).getBytes()); + } + } + fromVector.setValueCount(VECTOR_LENGTH); + } + + /** + * Tear down benchmarks. + */ + @TearDown + public void tearDown() { + vector.close(); + fromVector.close(); + allocator.close(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void copyFromBenchmark() { + for (int i = 0; i < VECTOR_LENGTH; i++) { + vector.copyFrom(i, i, fromVector); + } + } + + public static void main(String [] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(VarCharBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VariableWidthVectorBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VariableWidthVectorBenchmarks.java new file mode 100644 index 000000000..7eee981f1 --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VariableWidthVectorBenchmarks.java @@ -0,0 +1,130 @@ +/* + * 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.arrow.vector; + +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.ArrowBuf; +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.holders.NullableVarCharHolder; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +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; + +/** + * Benchmarks for {@link BaseVariableWidthVector}. + */ +@State(Scope.Benchmark) +public class VariableWidthVectorBenchmarks { + + private static final int VECTOR_CAPACITY = 16 * 1024; + + private static final int VECTOR_LENGTH = 1024; + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private static byte[] bytes = VariableWidthVectorBenchmarks.class.getName().getBytes(); + private ArrowBuf arrowBuff; + + private BufferAllocator allocator; + + private VarCharVector vector; + + /** + * Setup benchmarks. + */ + @Setup + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + vector = new VarCharVector("vector", allocator); + vector.allocateNew(VECTOR_CAPACITY, VECTOR_LENGTH); + arrowBuff = allocator.buffer(VECTOR_LENGTH); + arrowBuff.setBytes(0, bytes, 0, bytes.length); + } + + /** + * Tear down benchmarks. + */ + @TearDown + public void tearDown() { + arrowBuff.close(); + vector.close(); + allocator.close(); + } + + /** + * Test {@link BaseVariableWidthVector#getValueCapacity()}. + * @return useless. To avoid DCE by JIT. + */ + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public int getValueCapacity() { + return vector.getValueCapacity(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public int setSafeFromArray() { + for (int i = 0; i < 500; ++i) { + vector.setSafe(i * 40, bytes); + } + return vector.getBufferSize(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + public int setSafeFromNullableVarcharHolder() { + NullableVarCharHolder nvch = new NullableVarCharHolder(); + nvch.buffer = arrowBuff; + nvch.start = 0; + nvch.end = bytes.length; + for (int i = 0; i < 50; ++i) { + nvch.isSet = 0; + for (int j = 0; j < 9; ++j) { + int idx = 10 * i + j; + vector.setSafe(idx, nvch); + } + nvch.isSet = 1; + vector.setSafe(10 * (i + 1), nvch); + } + return vector.getBufferSize(); + } + + + public static void main(String [] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(VariableWidthVectorBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VectorLoaderBenchmark.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VectorLoaderBenchmark.java new file mode 100644 index 000000000..416d12641 --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VectorLoaderBenchmark.java @@ -0,0 +1,117 @@ +/* + * 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.arrow.vector; + +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.ipc.message.ArrowRecordBatch; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Level; +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.TearDown; +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; + +/** + * Benchmarks for {@link VectorLoader}. + */ +public class VectorLoaderBenchmark { + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private static final int VECTOR_COUNT = 10; + + /** + * State for vector load benchmark. + */ + @State(Scope.Benchmark) + public static class LoadState { + + private BufferAllocator allocator; + + private VarCharVector[] vectors; + + private ArrowRecordBatch recordBatch; + + private VectorSchemaRoot root; + + private VectorLoader loader; + + /** + * Setup benchmarks. + */ + @Setup(Level.Trial) + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + } + + @Setup(Level.Invocation) + public void prepareInvoke() { + vectors = new VarCharVector[VECTOR_COUNT]; + for (int i = 0; i < VECTOR_COUNT; i++) { + vectors[i] = new VarCharVector("vector", allocator); + vectors[i].allocateNew(100, 10); + } + + root = VectorSchemaRoot.of(vectors); + VectorUnloader unloader = new VectorUnloader(root); + recordBatch = unloader.getRecordBatch(); + + loader = new VectorLoader(root); + } + + @TearDown(Level.Invocation) + public void tearDownInvoke() { + recordBatch.close(); + root.close(); + } + + /** + * Tear down benchmarks. + */ + @TearDown(Level.Trial) + public void tearDown() { + allocator.close(); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void loadBenchmark(LoadState state) { + state.loader.load(state.recordBatch); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(VectorLoaderBenchmark.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VectorUnloaderBenchmark.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VectorUnloaderBenchmark.java new file mode 100644 index 000000000..d12517245 --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/VectorUnloaderBenchmark.java @@ -0,0 +1,109 @@ +/* + * 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.arrow.vector; + +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.ipc.message.ArrowRecordBatch; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Level; +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.TearDown; +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; + +/** + * Benchmarks for {@link VectorUnloader}. + */ +@State(Scope.Benchmark) +public class VectorUnloaderBenchmark { + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private static final int VECTOR_COUNT = 10; + + private BufferAllocator allocator; + + private VarCharVector [] vectors; + + private VectorUnloader unloader; + + private ArrowRecordBatch recordBatch; + + /** + * Setup benchmarks. + */ + @Setup(Level.Trial) + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + } + + @Setup(Level.Invocation) + public void prepareInvoke() { + vectors = new VarCharVector[VECTOR_COUNT]; + for (int i = 0; i < VECTOR_COUNT; i++) { + vectors[i] = new VarCharVector("vector", allocator); + vectors[i].allocateNew(100, 10); + } + + unloader = new VectorUnloader(VectorSchemaRoot.of(vectors)); + } + + @TearDown(Level.Invocation) + public void tearDownInvoke() { + if (recordBatch != null) { + recordBatch.close(); + } + for (int i = 0; i < VECTOR_COUNT; i++) { + vectors[i].close(); + } + } + + /** + * Tear down benchmarks. + */ + @TearDown(Level.Trial) + public void tearDown() { + allocator.close(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void unloadBenchmark() { + recordBatch = unloader.getRecordBatch(); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(VectorUnloaderBenchmark.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/dictionary/DictionaryEncoderBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/dictionary/DictionaryEncoderBenchmarks.java new file mode 100644 index 000000000..6dd887a32 --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/dictionary/DictionaryEncoderBenchmarks.java @@ -0,0 +1,147 @@ +/* + * 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.arrow.vector.dictionary; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.ValueVector; +import org.apache.arrow.vector.VarCharVector; +import org.apache.arrow.vector.types.pojo.DictionaryEncoding; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +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; + +/** + * Benchmarks for {@link DictionaryEncoder}. + */ +@State(Scope.Benchmark) +public class DictionaryEncoderBenchmarks { + + private BufferAllocator allocator; + + private static final int DATA_SIZE = 1000; + private static final int KEY_SIZE = 100; + + + private static final int KEY_LENGTH = 10; + + private List keys = new ArrayList<>(); + + private VarCharVector vector; + + private VarCharVector dictionaryVector; + + /** + * Setup benchmarks. + */ + @Setup + public void prepare() { + + for (int i = 0; i < KEY_SIZE; i++) { + keys.add(generateUniqueKey(KEY_LENGTH)); + } + + allocator = new RootAllocator(10 * 1024 * 1024); + + vector = new VarCharVector("vector", allocator); + dictionaryVector = new VarCharVector("dict", allocator); + + vector.allocateNew(10240, DATA_SIZE); + vector.setValueCount(DATA_SIZE); + for (int i = 0; i < DATA_SIZE; i++) { + byte[] value = keys.get(generateRandomIndex(KEY_SIZE)).getBytes(StandardCharsets.UTF_8); + vector.setSafe(i, value, 0, value.length); + } + + dictionaryVector.allocateNew(1024, 100); + dictionaryVector.setValueCount(100); + for (int i = 0; i < KEY_SIZE; i++) { + byte[] value = keys.get(i).getBytes(StandardCharsets.UTF_8); + dictionaryVector.setSafe(i, value, 0, value.length); + } + + } + + /** + * Tear down benchmarks. + */ + @TearDown + public void tearDown() { + vector.close(); + dictionaryVector.close(); + keys.clear(); + allocator.close(); + } + + /** + * Test encode for {@link DictionaryEncoder}. + * @return useless. To avoid DCE by JIT. + */ + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public int testEncode() { + Dictionary dictionary = new Dictionary(dictionaryVector, new DictionaryEncoding(1L, false, null)); + final ValueVector encoded = DictionaryEncoder.encode(vector, dictionary); + encoded.close(); + return 0; + } + + private int generateRandomIndex(int max) { + Random random = new Random(); + return random.nextInt(max); + } + + private String generateUniqueKey(int length) { + String str = "abcdefghijklmnopqrstuvwxyz"; + Random random = new Random(); + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < length; i++) { + int number = random.nextInt(26); + sb.append(str.charAt(number)); + } + if (keys.contains(sb.toString())) { + return generateUniqueKey(length); + } + return sb.toString(); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(DictionaryEncoderBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/ipc/WriteChannelBenchmark.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/ipc/WriteChannelBenchmark.java new file mode 100644 index 000000000..7a2537cbb --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/ipc/WriteChannelBenchmark.java @@ -0,0 +1,87 @@ +/* + * 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.arrow.vector.ipc; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.channels.Channels; +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Level; +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.TearDown; +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; + +/** + * Benchmarks for {@link WriteChannel}. + */ +public class WriteChannelBenchmark { + + /** + * State object for align benchmark. + */ + @State(Scope.Benchmark) + public static class AlignState { + + private ByteArrayOutputStream baos; + + private WriteChannel writeChannel; + + @Param({"1", "2", "3", "4", "5", "6", "7"}) + public int alignSize; + + @Setup(Level.Invocation) + public void prepareInvoke() throws IOException { + baos = new ByteArrayOutputStream(8); + writeChannel = new WriteChannel(Channels.newChannel(baos)); + writeChannel.write(new byte[8 - alignSize]); + } + + @TearDown(Level.Invocation) + public void tearDownInvoke() throws IOException { + writeChannel.close(); + baos.close(); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void alignBenchmark(AlignState state) throws IOException { + state.writeChannel.align(); + } + + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(WriteChannelBenchmark.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/ipc/message/ArrowRecordBatchBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/ipc/message/ArrowRecordBatchBenchmarks.java new file mode 100644 index 000000000..c0882821e --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/ipc/message/ArrowRecordBatchBenchmarks.java @@ -0,0 +1,98 @@ +/* + * 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.arrow.vector.ipc.message; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.VarCharVector; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +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; + +/** + * Benchmarks for {@link ArrowRecordBatch}. + */ +@State(Scope.Benchmark) +public class ArrowRecordBatchBenchmarks { + + private static final int VECTOR_CAPACITY = 16 * 1024; + + private static final int VECTOR_LENGTH = 1024; + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private BufferAllocator allocator; + + private VarCharVector vector; + + private List nodes; + + /** + * Setup benchmarks. + */ + @Setup + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + vector = new VarCharVector("vector", allocator); + vector.allocateNew(VECTOR_CAPACITY, VECTOR_LENGTH); + + nodes = new ArrayList<>(); + nodes.add(new ArrowFieldNode(VECTOR_LENGTH, 0)); + nodes.add(new ArrowFieldNode(VECTOR_LENGTH, 0)); + } + + /** + * Tear down benchmarks. + */ + @TearDown + public void tearDown() { + vector.close(); + allocator.close(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public long createAndGetLength() { + try (ArrowRecordBatch batch = new ArrowRecordBatch(VECTOR_LENGTH, nodes, vector.getFieldBuffers())) { + return batch.computeBodyLength(); + } + } + + public static void main(String [] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(ArrowRecordBatchBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} diff --git a/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/util/TransferPairBenchmarks.java b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/util/TransferPairBenchmarks.java new file mode 100644 index 000000000..235eca53c --- /dev/null +++ b/src/arrow/java/performance/src/test/java/org/apache/arrow/vector/util/TransferPairBenchmarks.java @@ -0,0 +1,123 @@ +/* + * 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.arrow.vector.util; + +import java.nio.charset.StandardCharsets; +import java.util.concurrent.TimeUnit; + +import org.apache.arrow.memory.BufferAllocator; +import org.apache.arrow.memory.RootAllocator; +import org.apache.arrow.vector.IntVector; +import org.apache.arrow.vector.VarCharVector; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +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.TearDown; +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; + +/** + * Benchmarks for {@link TransferPair}. + */ +@State(Scope.Benchmark) +public class TransferPairBenchmarks { + + private static final int VECTOR_LENGTH = 1024; + + private static final int ALLOCATOR_CAPACITY = 1024 * 1024; + + private BufferAllocator allocator; + + private IntVector intVector; + + private VarCharVector varCharVector; + + /** + * Setup benchmarks. + */ + @Setup + public void prepare() { + allocator = new RootAllocator(ALLOCATOR_CAPACITY); + intVector = new IntVector("intVector", allocator); + varCharVector = new VarCharVector("varcharVector", allocator); + + intVector.allocateNew(VECTOR_LENGTH); + varCharVector.allocateNew(VECTOR_LENGTH); + + for (int i = 0; i < VECTOR_LENGTH; i++) { + if (i % 3 == 0) { + intVector.setNull(i); + varCharVector.setNull(i); + } else { + intVector.setSafe(i, i * i); + varCharVector.setSafe(i, ("teststring" + i).getBytes(StandardCharsets.UTF_8)); + } + } + intVector.setValueCount(VECTOR_LENGTH); + varCharVector.setValueCount(VECTOR_LENGTH); + } + + /** + * Tear down benchmarks. + */ + @TearDown + public void tearDown() { + intVector.close(); + varCharVector.close();; + allocator.close(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public int splitAndTransferIntVector() { + IntVector toVector = new IntVector("intVector", allocator); + toVector.setValueCount(VECTOR_LENGTH); + TransferPair transferPair = intVector.makeTransferPair(toVector); + transferPair.splitAndTransfer(0, VECTOR_LENGTH); + toVector.close(); + return 0; + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public int splitAndTransferVarcharVector() { + VarCharVector toVector = new VarCharVector("varcharVector", allocator); + toVector.setValueCount(VECTOR_LENGTH); + TransferPair transferPair = varCharVector.makeTransferPair(toVector); + transferPair.splitAndTransfer(0, VECTOR_LENGTH); + toVector.close(); + return 0; + } + + public static void main(String [] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(TransferPairBenchmarks.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } +} -- cgit v1.2.3