Skip to content

Commit

Permalink
Add JMH Benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
ZacBlanco committed Apr 29, 2024
1 parent 0bff44b commit 102e383
Show file tree
Hide file tree
Showing 3 changed files with 359 additions and 1 deletion.
71 changes: 70 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ under the License.

<!-- Test -->
<testng.version>7.5.1</testng.version>
<jmh.version>1.37</jmh.version>
<!-- these are TestNG groups used for excluding / including groups of tests. See profiles section. -->
<testng.generate-java-files>generate_java_files</testng.generate-java-files>
<testng.check-cpp-files>check_cpp_files</testng.check-cpp-files>
Expand Down Expand Up @@ -148,6 +149,16 @@ under the License.
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
</dependency>
<!--
<dependency>
<groupId>org.apache.datasketches</groupId>
Expand Down Expand Up @@ -700,7 +711,7 @@ under the License.
</pluginManagement>
</build>
</profile>

<profile>
<id>check-cpp-historical-files</id>
<build>
Expand All @@ -719,5 +730,63 @@ under the License.
</pluginManagement>
</build>
</profile>

<profile>
<id>benchmarks</id>
<properties>
<uberjar.name>benchmarks</uberjar.name>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${uberjar.name}</finalName>
<shadeTestJar>true</shadeTestJar>

<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.apache.datasketches.kll.KllSketchBenchmarksByteSize</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
<filters>
<filter>
<!--
Shading signed JARs will fail without this.
http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar
-->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<groupId>org.apache.maven.plugins</groupId>
<version>3.2.1</version>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
* 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.datasketches.kll;

import org.apache.datasketches.common.ArrayOfDoublesSerDe;
import org.apache.datasketches.common.ArrayOfStringsSerDe;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OperationsPerInvocation;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
@Fork(value = 1)
@Warmup(iterations = 2, timeUnit = TimeUnit.NANOSECONDS, time = 60000)
@Measurement(iterations = 16, timeUnit = TimeUnit.NANOSECONDS, time = 60000)
public class KllSketchBenchmarksByteSize {

private static final char[] ALPHABET = "abcdefghijklmnopqrstuvwxyz1234567890".toCharArray();
private static final int DATA_SIZE = 16384;
KllFloatsSketch floatsSketch = KllFloatsSketch.newHeapInstance();
KllDoublesSketch doublesSketch = KllDoublesSketch.newHeapInstance();
KllItemsSketch<Double> itemsDoublesSketch = KllItemsSketch.newHeapInstance(Double::compareTo, new ArrayOfDoublesSerDe());
KllItemsSketch<String> itemsSketchString = KllItemsSketch.newHeapInstance(String::compareTo, new ArrayOfStringsSerDe());


@Setup
public void setup() {
IntStream.range(0, DATA_SIZE)
.map(x -> ThreadLocalRandom.current().nextInt(1024))
.mapToObj(stringLength -> IntStream.range(0, stringLength)
.mapToObj(item -> ThreadLocalRandom.current().nextInt(ALPHABET.length))
.map(idx -> Character.toString(ALPHABET[idx]))
.collect(Collectors.joining()))
.forEach(itemsSketchString::update);
IntStream.range(0, DATA_SIZE)
.mapToObj(x -> ThreadLocalRandom.current().nextFloat())
.forEach(floatsSketch::update);
IntStream.range(0, DATA_SIZE)
.mapToDouble(x -> ThreadLocalRandom.current().nextDouble())
.forEach(item -> {
doublesSketch.update(item);
itemsDoublesSketch.update(item);
});

}

/* getSerializedSizeBytes() */

@Benchmark
@OperationsPerInvocation(4096)
public void getSerializedSizeBytesItemsString() {
for (int i = 0; i < 4096; i++) {
itemsSketchString.getSerializedSizeBytes();
}
}

@Benchmark
@OperationsPerInvocation(4096)
public void getSerializedSizeBytesItemsDouble() {
for (int i = 0; i < 4096; i++) {
itemsDoublesSketch.getSerializedSizeBytes();
}
}

@Benchmark
@OperationsPerInvocation(4096)
public void getSerializedSizeBytesRawDouble() {
for (int i = 0; i < 4096; i++) {
doublesSketch.getSerializedSizeBytes();
}
}

@Benchmark
@OperationsPerInvocation(4096)
public void getSerializedSizeBytesRawFloat() {
for (int i = 0; i < 4096; i++) {
floatsSketch.getSerializedSizeBytes();
}
}

/* getTotalItemsNumBytes() */

@Benchmark
@OperationsPerInvocation(4096)
public void getTotalItemsNumBytesItemsString() {
for (int i = 0; i < 4096; i++) {
itemsSketchString.getTotalItemsNumBytes();
}
}

@Benchmark
@OperationsPerInvocation(4096)
public void getTotalItemsNumBytesItemsDouble() {
for (int i = 0; i < 4096; i++) {
itemsDoublesSketch.getTotalItemsNumBytes();
}
}

@Benchmark
@OperationsPerInvocation(4096)
public void getTotalItemsNumBytesRawDouble() {
for (int i = 0; i < 4096; i++) {
doublesSketch.getTotalItemsNumBytes();
}
}

@Benchmark
@OperationsPerInvocation(4096)
public void getTotalItemsNumBytesRawFloat() {
for (int i = 0; i < 4096; i++) {
floatsSketch.getTotalItemsNumBytes();
}
}

public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(KllSketchBenchmarksByteSize.class.getSimpleName())
.forks(1)
.resultFormat(ResultFormatType.CSV)
.build();

new Runner(opt).run();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* 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.datasketches.kll;

import org.apache.datasketches.common.ArrayOfDoublesSerDe;
import org.apache.datasketches.common.ArrayOfStringsSerDe;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OperationsPerInvocation;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.nio.FloatBuffer;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
@Fork(value = 1)
@Warmup(iterations = 2, timeUnit = TimeUnit.NANOSECONDS, time = 60000)
@Measurement(iterations = 16, timeUnit = TimeUnit.NANOSECONDS, time = 60000)
public class KllSketchBenchmarksUpdate {

private static final char[] ALPHABET = "abcdefghijklmnopqrstuvwxyz1234567890".toCharArray();
private static final int DATA_SIZE = 4096;
private String[] stringData;
private float[] floatData;
private double[] doubleData;
KllFloatsSketch floatsSketch = KllFloatsSketch.newHeapInstance();
KllDoublesSketch doublesSketch = KllDoublesSketch.newHeapInstance();
KllItemsSketch<Double> itemsDoublesSketch = KllItemsSketch.newHeapInstance(Double::compareTo, new ArrayOfDoublesSerDe());
KllItemsSketch<String> itemsSketchString = KllItemsSketch.newHeapInstance(String::compareTo, new ArrayOfStringsSerDe());
int currentIndex = 0;


@Setup
public void setup() {
stringData = IntStream.range(0, DATA_SIZE)
.map(x -> ThreadLocalRandom.current().nextInt(1024))
.mapToObj(stringLength -> IntStream.range(0, stringLength)
.mapToObj(item -> ThreadLocalRandom.current().nextInt(ALPHABET.length))
.map(idx -> Character.toString(ALPHABET[idx]))
.collect(Collectors.joining()))
.toArray(String[]::new);
FloatBuffer tmp = FloatBuffer.allocate(DATA_SIZE);
IntStream.range(0, DATA_SIZE)
.mapToObj(x -> ThreadLocalRandom.current().nextFloat())
.forEach(tmp::put);
floatData = tmp.array();
doubleData = IntStream.range(0, DATA_SIZE)
.mapToDouble(x -> ThreadLocalRandom.current().nextDouble())
.toArray();

}


@Benchmark
@OperationsPerInvocation(4096)
public void updateRawDoubles() {
for (int i = 0; i < 4096; i++) {
doublesSketch.update(doubleData[currentIndex++ % DATA_SIZE]);
}
}

@Benchmark
@OperationsPerInvocation(4096)
public void updateRawFloats() {
for (int i = 0; i < 4096; i++) {
floatsSketch.update(floatData[currentIndex++ % DATA_SIZE]);
}
}

@Benchmark
@OperationsPerInvocation(4096)
public void updateItemsDouble() {
for (int i = 0; i < 4096; i++) {
itemsDoublesSketch.update(doubleData[currentIndex++ % DATA_SIZE]);
}
}

@Benchmark
@OperationsPerInvocation(4096)
public void updateItemsStrings() {
for (int i = 0; i < 4096; i++) {
itemsSketchString.update(stringData[currentIndex++ % DATA_SIZE]);
}
}

public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(KllSketchBenchmarksUpdate.class.getSimpleName())
.forks(1)
.resultFormat(ResultFormatType.CSV)
.build();

new Runner(opt).run();
}
}

0 comments on commit 102e383

Please sign in to comment.