Skip to content

Commit 1d397e3

Browse files
committed
Add benchmarks.
1 parent 3bf53d6 commit 1d397e3

File tree

5 files changed

+197
-0
lines changed

5 files changed

+197
-0
lines changed

pom.xml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,28 @@
390390
</resources>
391391
</build>
392392
</profile>
393+
<profile>
394+
<id>jmh</id>
395+
<dependencies>
396+
<dependency>
397+
<groupId>org.openjdk.jmh</groupId>
398+
<artifactId>jmh-core</artifactId>
399+
<scope>test</scope>
400+
<version>${jmh}</version>
401+
</dependency>
402+
<dependency>
403+
<groupId>org.openjdk.jmh</groupId>
404+
<artifactId>jmh-generator-annprocess</artifactId>
405+
<scope>test</scope>
406+
</dependency>
407+
</dependencies>
408+
<repositories>
409+
<repository>
410+
<id>jitpack.io</id>
411+
<url>https://jitpack.io</url>
412+
</repository>
413+
</repositories>
414+
</profile>
393415
</profiles>
394416

395417
<repositories>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data;
17+
18+
import java.util.concurrent.TimeUnit;
19+
20+
import org.openjdk.jmh.annotations.BenchmarkMode;
21+
import org.openjdk.jmh.annotations.Fork;
22+
import org.openjdk.jmh.annotations.Measurement;
23+
import org.openjdk.jmh.annotations.Mode;
24+
import org.openjdk.jmh.annotations.OutputTimeUnit;
25+
import org.openjdk.jmh.annotations.Warmup;
26+
27+
/**
28+
* Global benchmark settings.
29+
*
30+
* @author Mark Paluch
31+
*/
32+
@Warmup(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
33+
@Measurement(iterations = 5, time = 1000, timeUnit = TimeUnit.MILLISECONDS)
34+
@Fork(value = 1, warmups = 0)
35+
@BenchmarkMode(Mode.Throughput)
36+
@OutputTimeUnit(TimeUnit.SECONDS)
37+
public abstract class BenchmarkSettings {
38+
39+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.core;
17+
18+
import org.junit.platform.commons.annotation.Testable;
19+
import org.openjdk.jmh.annotations.Benchmark;
20+
21+
import org.springframework.data.BenchmarkSettings;
22+
23+
/**
24+
* Benchmarks for {@link SerializableLambdaReader}.
25+
*
26+
* @author Mark Paluch
27+
*/
28+
@Testable
29+
public class SerializableLambdaReaderBenchmarks extends BenchmarkSettings {
30+
31+
private static final SerializableLambdaReader reader = new SerializableLambdaReader(MemberReference.class);
32+
33+
@Benchmark
34+
public Object benchmarkMethodReference() {
35+
36+
MemberReference<Person, String> methodReference = Person::firstName;
37+
return reader.read(methodReference);
38+
}
39+
40+
@Benchmark
41+
public Object benchmarkLambda() {
42+
43+
MemberReference<Person, String> methodReference = person -> person.firstName();
44+
return reader.read(methodReference);
45+
}
46+
47+
record Person(String firstName, String lastName) {
48+
49+
}
50+
51+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.core;
17+
18+
import org.junit.platform.commons.annotation.Testable;
19+
import org.openjdk.jmh.annotations.Benchmark;
20+
21+
import org.springframework.data.BenchmarkSettings;
22+
23+
/**
24+
* Benchmarks for {@link TypedPropertyPath}.
25+
*
26+
* @author Mark Paluch
27+
*/
28+
@Testable
29+
public class TypedPropertyPathBenchmarks extends BenchmarkSettings {
30+
31+
@Benchmark
32+
public Object benchmarkMethodReference() {
33+
return TypedPropertyPath.of(Person::firstName);
34+
}
35+
36+
@Benchmark
37+
public Object benchmarkComposedMethodReference() {
38+
return TypedPropertyPath.of(Person::address).then(Address::city);
39+
}
40+
41+
@Benchmark
42+
public TypedPropertyPath<Person, String> benchmarkLambda() {
43+
return TypedPropertyPath.of(person -> person.firstName());
44+
}
45+
46+
@Benchmark
47+
public TypedPropertyPath<Person, String> benchmarkComposedLambda() {
48+
return TypedPropertyPath.of((Person person) -> person.address()).then(address -> address.city());
49+
}
50+
51+
@Benchmark
52+
public Object dotPath() {
53+
return TypedPropertyPath.of(Person::firstName).toDotPath();
54+
}
55+
56+
@Benchmark
57+
public Object composedDotPath() {
58+
return TypedPropertyPath.of(Person::address).then(Address::city).toDotPath();
59+
}
60+
61+
record Person(String firstName, String lastName, Address address) {
62+
63+
}
64+
65+
record Address(String city) {
66+
67+
}
68+
69+
}

src/test/java/org/springframework/data/core/TypedPropertyPathUnitTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static org.assertj.core.api.Assertions.*;
1919

2020
import org.jspecify.annotations.Nullable;
21+
import org.junit.jupiter.api.Nested;
2122
import org.junit.jupiter.api.Test;
2223
import org.springframework.dao.InvalidDataAccessApiUsageException;
2324

@@ -200,6 +201,21 @@ void failsResolvingCallingLocalMethod() {
200201
}));
201202
}
202203

204+
@Nested
205+
class NestedTestClass {
206+
207+
@Test
208+
void resolvesInterfaceLambdaGetter() {
209+
assertThat(PropertyPath.of((PersonProjection person) -> person.getName()).toDotPath()).isEqualTo("name");
210+
}
211+
212+
@Test
213+
void resolvesSuperclassMethodReferenceGetter() {
214+
assertThat(PropertyPath.of(PersonQuery::getTenant).toDotPath()).isEqualTo("tenant");
215+
}
216+
217+
}
218+
203219
// Domain entities
204220

205221
static public class SuperClass {

0 commit comments

Comments
 (0)