Skip to content

Commit 747625b

Browse files
christophstroblmp911de
authored andcommitted
DATAMONGO-1720 - Add JMH based benchmarks for MappingMongoConverter.
Run the benchmark via the maven profile "benchmarks": mvn -P benchmarks clean test Or run them customized: mvn -P benchmarks -DwarmupIterations=2 -DmeasurementIterations=5 -Dforks=1 clean test Origin pull request: spring-projects#483.
1 parent 3dee8de commit 747625b

File tree

10 files changed

+1054
-0
lines changed

10 files changed

+1054
-0
lines changed

pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<module>spring-data-mongodb</module>
2323
<module>spring-data-mongodb-cross-store</module>
2424
<module>spring-data-mongodb-distribution</module>
25+
<module>spring-data-mongodb-benchmarks</module>
2526
</modules>
2627

2728
<properties>
@@ -30,6 +31,7 @@
3031
<springdata.commons>2.0.0.BUILD-SNAPSHOT</springdata.commons>
3132
<mongo>3.4.2</mongo>
3233
<mongo.reactivestreams>1.5.0</mongo.reactivestreams>
34+
<jmh.version>1.19</jmh.version>
3335
</properties>
3436

3537
<developers>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Benchmarks
2+
3+
Benchmarks are based on [JMH](http://openjdk.java.net/projects/code-tools/jmh/).
4+
5+
# Running Benchmarks
6+
7+
Running benchmarks is disabled by default and can be activated via the `benchmarks` profile.
8+
To run the benchmarks with default settings use.
9+
10+
```bash
11+
mvn -P benchmarks clean test
12+
```
13+
14+
A basic report will be printed to the CLI.
15+
16+
```bash
17+
# Run complete. Total time: 00:00:15
18+
19+
Benchmark Mode Cnt Score Error Units
20+
MappingMongoConverterBenchmark.readObject thrpt 10 1920157,631 ± 64310,809 ops/s
21+
MappingMongoConverterBenchmark.writeObject thrpt 10 782732,857 ± 53804,130 ops/s
22+
```
23+
24+
## Running all Benchmarks of a specific class
25+
26+
To run all Benchmarks of a specific class, just provide its simple class name via the `benchmark` command line argument.
27+
28+
```bash
29+
mvn -P benchmarks clean test -D benchmark=MappingMongoConverterBenchmark
30+
```
31+
32+
## Running a single Benchmark
33+
34+
To run a single Benchmark provide its containing class simple name followed by `#` and the method name via the `benchmark` command line argument.
35+
36+
```bash
37+
mvn -P benchmarks clean test -D benchmark=MappingMongoConverterBenchmark#readObjectWith2Properties
38+
```
39+
40+
# Saving Benchmark Results
41+
42+
A detailed benchmark report is stored in JSON format in the `/target/reports/performance` directory.
43+
To store the report in a different location use the `benchmarkReportDir` command line argument.
44+
45+
## MongoDB
46+
47+
Results can be directly piped to MongoDB by providing a valid [Connection String](https://docs.mongodb.com/manual/reference/connection-string/) via the `publishTo` command line argument.
48+
49+
```bash
50+
mvn -P benchmarks clean test -D publishTo=mongodb://127.0.0.1:27017
51+
```
52+
53+
NOTE: If the uri does not explicitly define a database the default `spring-data-mongodb-benchmarks` is used.
54+
55+
## HTTP Endpoint
56+
57+
The benchmark report can also be posted as `application/json` to an HTTP Endpoint by providing a valid URl via the `publishTo` command line argument.
58+
59+
```bash
60+
mvn -P benchmarks clean test -D publishTo=http://127.0.0.1:8080/capture-benchmarks
61+
```
62+
63+
# Customizing Benchmarks
64+
65+
Following options can be set via command line.
66+
67+
Option | Default Value
68+
--- | ---
69+
warmupIterations | 10
70+
warmupTime | 1 (seconds)
71+
measurementIterations | 10
72+
measurementTime | 1 (seconds)
73+
forks | 1
74+
benchmarkReportDir | /target/reports/performance (always relative to project root dir)
75+
benchmark | .* (single benchmark via `classname#benchmark`)
76+
publishTo | \[not set\] (mongodb-uri or http-endpoint)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4+
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>org.springframework.data</groupId>
9+
<artifactId>spring-data-mongodb-parent</artifactId>
10+
<version>2.0.0.BUILD-SNAPSHOT</version>
11+
<relativePath>../pom.xml</relativePath>
12+
</parent>
13+
14+
<artifactId>spring-data-mongodb-benchmarks</artifactId>
15+
<packaging>jar</packaging>
16+
17+
<name>Spring Data MongoDB - Microbenchmarks</name>
18+
19+
<properties>
20+
<skipTests>true</skipTests> <!-- Skip tests by default; run only if -DskipTests=false is specified or benchmarks profile is activated -->
21+
<bundlor.enabled>false</bundlor.enabled>
22+
</properties>
23+
24+
<dependencies>
25+
<dependency>
26+
<groupId>${project.groupId}</groupId>
27+
<artifactId>spring-data-mongodb</artifactId>
28+
<version>${project.version}</version>
29+
</dependency>
30+
<dependency>
31+
<groupId>junit</groupId>
32+
<artifactId>junit</artifactId>
33+
<version>${junit}</version>
34+
<scope>compile</scope>
35+
</dependency>
36+
<dependency>
37+
<groupId>org.openjdk.jmh</groupId>
38+
<artifactId>jmh-core</artifactId>
39+
<version>${jmh.version}</version>
40+
</dependency>
41+
<dependency>
42+
<groupId>org.openjdk.jmh</groupId>
43+
<artifactId>jmh-generator-annprocess</artifactId>
44+
<version>${jmh.version}</version>
45+
<scope>provided</scope>
46+
</dependency>
47+
</dependencies>
48+
49+
<profiles>
50+
51+
<profile>
52+
<id>benchmarks</id>
53+
<properties>
54+
<skipTests>false</skipTests>
55+
</properties>
56+
</profile>
57+
</profiles>
58+
59+
<build>
60+
<plugins>
61+
<plugin>
62+
<artifactId>maven-jar-plugin</artifactId>
63+
<executions>
64+
<execution>
65+
<id>default-jar</id>
66+
<phase>never</phase>
67+
</execution>
68+
</executions>
69+
</plugin>
70+
<plugin>
71+
<artifactId>maven-surefire-plugin</artifactId>
72+
<configuration>
73+
<testSourceDirectory>${project.build.sourceDirectory}</testSourceDirectory>
74+
<testClassesDirectory>${project.build.outputDirectory}</testClassesDirectory>
75+
<excludes>
76+
<exclude>**/AbstractMicrobenchmark.java</exclude>
77+
<exclude>**/*$*.class</exclude>
78+
<exclude>**/generated/*.class</exclude>
79+
</excludes>
80+
<includes>
81+
<include>**/*Benchmark*</include>
82+
</includes>
83+
<systemPropertyVariables>
84+
<benchmarkReportDir>${project.build.directory}/reports/performance</benchmarkReportDir>
85+
<project.version>${project.version}</project.version>
86+
</systemPropertyVariables>
87+
</configuration>
88+
</plugin>
89+
</plugins>
90+
</build>
91+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright 2017 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+
* http://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.mongodb.core.convert;
17+
18+
import static org.springframework.data.mongodb.core.query.Criteria.*;
19+
import static org.springframework.data.mongodb.core.query.Query.*;
20+
21+
import lombok.Data;
22+
23+
import java.util.ArrayList;
24+
import java.util.List;
25+
26+
import org.bson.types.ObjectId;
27+
import org.openjdk.jmh.annotations.Benchmark;
28+
import org.openjdk.jmh.annotations.Scope;
29+
import org.openjdk.jmh.annotations.Setup;
30+
import org.openjdk.jmh.annotations.State;
31+
import org.openjdk.jmh.annotations.TearDown;
32+
import org.springframework.data.annotation.Id;
33+
import org.springframework.data.mongodb.core.MongoTemplate;
34+
import org.springframework.data.mongodb.core.mapping.DBRef;
35+
import org.springframework.data.mongodb.core.query.Query;
36+
import org.springframework.data.mongodb.microbenchmark.AbstractMicrobenchmark;
37+
38+
import com.mongodb.MongoClient;
39+
import com.mongodb.ServerAddress;
40+
41+
/**
42+
* @author Christoph Strobl
43+
*/
44+
@State(Scope.Benchmark)
45+
public class DbRefMappingBenchmark extends AbstractMicrobenchmark {
46+
47+
private static final String DB_NAME = "dbref-loading-benchmark";
48+
49+
private MongoClient client;
50+
private MongoTemplate template;
51+
52+
private Query queryObjectWithDBRef;
53+
private Query queryObjectWithDBRefList;
54+
55+
@Setup
56+
public void setUp() throws Exception {
57+
58+
client = new MongoClient(new ServerAddress());
59+
template = new MongoTemplate(client, DB_NAME);
60+
61+
List<RefObject> refObjects = new ArrayList<>();
62+
for (int i = 0; i < 1; i++) {
63+
RefObject o = new RefObject();
64+
template.save(o);
65+
refObjects.add(o);
66+
}
67+
68+
ObjectWithDBRef singleDBRef = new ObjectWithDBRef();
69+
singleDBRef.ref = refObjects.iterator().next();
70+
template.save(singleDBRef);
71+
72+
ObjectWithDBRef multipleDBRefs = new ObjectWithDBRef();
73+
multipleDBRefs.refList = refObjects;
74+
template.save(multipleDBRefs);
75+
76+
queryObjectWithDBRef = query(where("id").is(singleDBRef.id));
77+
queryObjectWithDBRefList = query(where("id").is(multipleDBRefs.id));
78+
}
79+
80+
@TearDown
81+
public void tearDown() {
82+
83+
client.dropDatabase(DB_NAME);
84+
client.close();
85+
}
86+
87+
@Benchmark // DATAMONGO-1720
88+
public ObjectWithDBRef readSingleDbRef() {
89+
return template.findOne(queryObjectWithDBRef, ObjectWithDBRef.class);
90+
}
91+
92+
@Benchmark // DATAMONGO-1720
93+
public ObjectWithDBRef readMultipleDbRefs() {
94+
return template.findOne(queryObjectWithDBRefList, ObjectWithDBRef.class);
95+
}
96+
97+
@Data
98+
static class ObjectWithDBRef {
99+
100+
private @Id ObjectId id;
101+
private @DBRef RefObject ref;
102+
private @DBRef List<RefObject> refList;
103+
}
104+
105+
@Data
106+
static class RefObject {
107+
108+
private @Id String id;
109+
private String someValue;
110+
}
111+
}

0 commit comments

Comments
 (0)