Skip to content

Commit 8e50ba5

Browse files
committed
Add benchmark for unified function
Signed-off-by: Chen Dai <daichen@amazon.com>
1 parent 0762a1a commit 8e50ba5

3 files changed

Lines changed: 122 additions & 2 deletions

File tree

benchmarks/build.gradle

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
plugins {
77
id 'java-library'
8+
id "io.freefair.lombok"
9+
id 'com.diffplug.spotless'
810
id "me.champeau.jmh" version "0.7.3"
911
}
1012

@@ -27,8 +29,17 @@ spotless {
2729
java {
2830
target fileTree('.') {
2931
include '**/*.java'
30-
exclude '**/jmh_generated/**'
32+
exclude '**/jmh_generated/**', '**/build/**'
3133
}
34+
importOrder()
35+
licenseHeader("/*\n" +
36+
" * Copyright OpenSearch Contributors\n" +
37+
" * SPDX-License-Identifier: Apache-2.0\n" +
38+
" */\n\n")
39+
removeUnusedImports()
40+
trimTrailingWhitespace()
41+
endWithNewline()
42+
googleJavaFormat('1.32.0').reflowLongStrings().groupArtifact('com.google.googlejavaformat:google-java-format')
3243
}
3344
}
3445

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.sql.api;
7+
8+
import java.util.List;
9+
import java.util.concurrent.TimeUnit;
10+
import lombok.RequiredArgsConstructor;
11+
import org.openjdk.jmh.annotations.Benchmark;
12+
import org.openjdk.jmh.annotations.BenchmarkMode;
13+
import org.openjdk.jmh.annotations.Fork;
14+
import org.openjdk.jmh.annotations.Level;
15+
import org.openjdk.jmh.annotations.Measurement;
16+
import org.openjdk.jmh.annotations.Mode;
17+
import org.openjdk.jmh.annotations.OperationsPerInvocation;
18+
import org.openjdk.jmh.annotations.OutputTimeUnit;
19+
import org.openjdk.jmh.annotations.Param;
20+
import org.openjdk.jmh.annotations.Scope;
21+
import org.openjdk.jmh.annotations.Setup;
22+
import org.openjdk.jmh.annotations.State;
23+
import org.openjdk.jmh.annotations.TearDown;
24+
import org.openjdk.jmh.annotations.Warmup;
25+
import org.openjdk.jmh.infra.Blackhole;
26+
import org.opensearch.sql.api.function.UnifiedFunction;
27+
import org.opensearch.sql.api.function.UnifiedFunctionRepository;
28+
29+
/**
30+
* JMH benchmark for measuring {@link UnifiedFunction} performance. Tests one representative
31+
* function per PPL category (json, math, conditional, collection, string).
32+
*
33+
* <p>Benchmarks:
34+
*
35+
* <ul>
36+
* <li>{@link #loadFunction()}: Measures function loading from repository
37+
* <li>{@link #evalFunction(Blackhole)}: Measures function evaluation (1000 calls per invocation)
38+
* </ul>
39+
*/
40+
@Warmup(iterations = 2, time = 1)
41+
@Measurement(iterations = 5, time = 1)
42+
@BenchmarkMode(Mode.AverageTime)
43+
@OutputTimeUnit(TimeUnit.MILLISECONDS)
44+
@State(Scope.Thread)
45+
@Fork(value = 1)
46+
public class UnifiedFunctionBenchmark extends UnifiedQueryTestBase {
47+
48+
private static final int OPS = 1000;
49+
50+
@Param public BenchmarkCase benchmarkCase;
51+
52+
private UnifiedFunctionRepository repository;
53+
private UnifiedFunction function;
54+
private List<Object> inputs;
55+
56+
@Setup(Level.Trial)
57+
public void setUpBenchmark() {
58+
super.setUp();
59+
60+
repository = new UnifiedFunctionRepository(context);
61+
function = benchmarkCase.loadFunction(repository);
62+
inputs = benchmarkCase.inputs();
63+
}
64+
65+
@TearDown(Level.Trial)
66+
public void tearDownBenchmark() throws Exception {
67+
super.tearDown();
68+
}
69+
70+
/** Benchmarks function loading from repository. */
71+
@Benchmark
72+
public UnifiedFunction loadFunction() {
73+
return benchmarkCase.loadFunction(repository);
74+
}
75+
76+
/** Benchmarks function evaluation with pre-loaded function and inputs. */
77+
@Benchmark
78+
@OperationsPerInvocation(OPS)
79+
public void evalFunction(Blackhole bh) {
80+
for (int i = 0; i < OPS; i++) {
81+
bh.consume(function.eval(inputs));
82+
}
83+
}
84+
85+
/** Enum defining benchmark test cases - one representative function per PPL category. */
86+
@RequiredArgsConstructor
87+
public enum BenchmarkCase {
88+
JSON_EXTRACT(
89+
List.of("VARCHAR", "VARCHAR"), List.of("{\"name\":\"test\",\"value\":42}", "$.name")),
90+
MOD(List.of("INTEGER", "INTEGER"), List.of(17, 5)),
91+
COALESCE(List.of("VARCHAR", "VARCHAR"), List.of("first_value", "default_value")),
92+
ARRAY(List.of("INTEGER", "INTEGER", "INTEGER"), List.of(1, 2, 3)),
93+
SHA2(List.of("VARCHAR", "INTEGER"), List.of("hello world", 256));
94+
95+
private final List<String> inputTypes;
96+
private final List<Object> inputs;
97+
98+
UnifiedFunction loadFunction(UnifiedFunctionRepository repository) {
99+
return repository
100+
.loadFunction(name())
101+
.map(desc -> desc.getBuilder().build(inputTypes))
102+
.orElseThrow();
103+
}
104+
105+
List<Object> inputs() {
106+
return inputs;
107+
}
108+
}
109+
}

benchmarks/src/jmh/java/org/opensearch/sql/api/UnifiedQueryBenchmark.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
@Warmup(iterations = 2, time = 1)
5151
@Measurement(iterations = 5, time = 1)
5252
@BenchmarkMode(Mode.AverageTime)
53-
@OutputTimeUnit(TimeUnit.MICROSECONDS)
53+
@OutputTimeUnit(TimeUnit.MILLISECONDS)
5454
@State(Scope.Thread)
5555
@Fork(value = 1)
5656
public class UnifiedQueryBenchmark extends UnifiedQueryTestBase {

0 commit comments

Comments
 (0)