Replace Guava Stopwatch for benchmarks

This commit is contained in:
Jan-Willem Gmelig Meyling 2020-11-14 22:03:19 +01:00
parent 73e8305049
commit f1be28ab37
10 changed files with 242 additions and 253 deletions

View File

@ -528,6 +528,9 @@
<version>6.6</version>
</dependency>
</dependencies>
<configuration>
<excludes>**/generated/**/*</excludes>
</configuration>
</plugin>
</plugins>
</build>

View File

@ -13,7 +13,6 @@ import javax.persistence.*;
import org.junit.Test;
import com.google.common.collect.ForwardingSet;
import com.querydsl.apt.domain.AbstractEntityTest;
import com.querydsl.apt.domain.CustomCollection;
import com.querydsl.apt.domain.Generic2Test;
@ -68,14 +67,12 @@ public class GenericExporterTest extends AbstractProcessorTest {
exporter.setSupertypeAnnotation(MappedSuperclass.class);
exporter.setSkipAnnotation(Transient.class);
exporter.setTargetFolder(new File("target/GenericExporterTest2"));
exporter.addStopClass(ForwardingSet.class);
exporter.setStrictMode(true);
exporter.setPropertyHandling(PropertyHandling.JPA);
exporter.export(AbstractEntityTest.class.getPackage(), A.class.getPackage());
List<String> expected = new ArrayList<String>();
// GenericExporter doesn't include field/method selection
expected.add("QCustomCollection_MyCustomCollection2.java");
expected.add("QTemporalTest_MyEntity.java");
expected.add("QTemporal2Test_Cheque.java");
expected.add("QQueryProjectionTest_DTOWithProjection.java");
@ -106,7 +103,6 @@ public class GenericExporterTest extends AbstractProcessorTest {
exporter.setSkipAnnotation(Transient.class);
exporter.setTargetFolder(new File("target/GenericExporterTest3"));
exporter.setPropertyHandling(PropertyHandling.JPA);
//exporter.addStopClass(ForwardingSet.class);
exporter.export(CustomCollection.MyCustomCollection.class,
CustomCollection.MyCustomCollection2.class,
CustomCollection.MyEntity.class);
@ -123,7 +119,6 @@ public class GenericExporterTest extends AbstractProcessorTest {
exporter.setSkipAnnotation(Transient.class);
exporter.setTargetFolder(new File("target/GenericExporterTest4"));
exporter.setPropertyHandling(PropertyHandling.JPA);
exporter.addStopClass(ForwardingSet.class);
exporter.export(Generic2Test.class.getClasses());
}

View File

@ -1,31 +1,40 @@
package com.querydsl.apt.domain;
import java.util.Set;
import java.util.AbstractSet;
import java.util.Iterator;
import javax.persistence.Entity;
import com.google.common.collect.ForwardingSet;
public class CustomCollection {
@Entity
public static class MyCustomCollection<T> extends ForwardingSet<T> {
public static class MyCustomCollection<T> extends AbstractSet<T> {
@Override
protected Set<T> delegate() {
public Iterator<T> iterator() {
return null;
}
@Override
public int size() {
return 0;
}
}
@Entity
public static class MyCustomCollection2 extends ForwardingSet<String> {
public static class MyCustomCollection2<T> extends AbstractSet<T> {
@Override
protected Set<String> delegate() {
public Iterator<T> iterator() {
return null;
}
@Override
public int size() {
return 0;
}
}
@Entity

View File

@ -67,6 +67,20 @@
<version>${cglib.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.21</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.21</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>joda-time</groupId>

View File

@ -3,15 +3,23 @@ package com.querydsl.collections;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import com.querydsl.core.testutil.Benchmark;
import com.querydsl.core.testutil.Performance;
import com.querydsl.core.testutil.Runner;
import org.openjdk.jmh.runner.Runner;
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.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.openjdk.jmh.runner.options.TimeValue;
@Ignore
@Category(Performance.class)
@ -28,19 +36,32 @@ public class QueryPerformanceTest {
}
}
@Test
public void byId() throws Exception {
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void benchmark1() {
// 15857
Runner.run("by id", new Benchmark() {
@Override
public void run(int times) throws Exception {
for (int i = 0; i < times; i++) {
QCat cat = QCat.cat;
CollQueryFactory.from(cat, cats).where(cat.id.eq(i % size)).select(cat).fetch();
}
}
});
QCat cat = QCat.cat;
CollQueryFactory.from(cat, cats).where(cat.id.eq(ThreadLocalRandom.current().nextInt(100) % size)).select(cat).fetch();
}
@Test
public void launchBenchmark() throws Exception {
Options opt = new OptionsBuilder()
.include(this.getClass().getName() + ".*")
.mode(Mode.AverageTime)
.timeUnit(TimeUnit.MICROSECONDS)
.warmupTime(TimeValue.seconds(1))
.warmupIterations(3)
.measurementTime(TimeValue.seconds(1))
.measurementIterations(3)
.threads(2)
.forks(1)
.shouldFailOnError(true)
.shouldDoGC(true)
.build();
new Runner(opt).run();
}
}

View File

@ -1,20 +0,0 @@
/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* Licensed 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 com.querydsl.core.testutil;
public interface Benchmark {
void run(int times) throws Exception;
}

View File

@ -1,40 +0,0 @@
/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* Licensed 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 com.querydsl.core.testutil;
import com.google.common.base.Stopwatch;
public final class Runner {
private static final int WARMUP = 50000;
private static final int BENCHMARK = 1000000;
public static void run(String label, Benchmark benchmark) throws Exception {
// warmup
benchmark.run(WARMUP);
System.err.print("- ");
// run garbage collection
System.gc();
System.err.print("- ");
// perform timing
Stopwatch stopwatch = Stopwatch.createStarted();
benchmark.run(BENCHMARK);
System.err.println(label + " " + stopwatch.stop().toString());
}
private Runner() { }
}

View File

@ -173,6 +173,20 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.21</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.21</version>
<scope>test</scope>
</dependency>
<!-- backwards compatibility -->
<dependency>
<groupId>org.jvnet.hudson</groupId>

View File

@ -111,9 +111,9 @@ public final class Connections {
return DriverManager.getConnection(url, "sa", "");
}
private static Connection getH2() throws SQLException, ClassNotFoundException {
public static Connection getH2() throws SQLException, ClassNotFoundException {
Class.forName("org.h2.Driver");
String url = "jdbc:h2:./target/h2-test;LOCK_MODE=0";
String url = "jdbc:h2:./target/h2-test;LOCK_MODE=0;AUTO_SERVER=TRUE";
return DriverManager.getConnection(url, "sa", "");
}

View File

@ -1,22 +1,33 @@
package com.querydsl.sql;
import static org.junit.Assert.assertNotNull;
import java.sql.*;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import com.mysema.commons.lang.CloseableIterator;
import com.querydsl.core.DefaultQueryMetadata;
import com.querydsl.core.JoinType;
import com.querydsl.core.QueryMetadata;
import com.querydsl.core.testutil.Benchmark;
import com.querydsl.core.testutil.H2;
import com.querydsl.core.testutil.Performance;
import com.querydsl.core.testutil.Runner;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
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.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.openjdk.jmh.runner.options.TimeValue;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertNotNull;
@Category({H2.class, Performance.class})
public class QueryPerformanceTest {
@ -29,8 +40,6 @@ public class QueryPerformanceTest {
private static final Configuration conf = new Configuration(templates);
private final Connection conn = Connections.getConnection();
@BeforeClass
public static void setUpClass() throws SQLException, ClassNotFoundException {
Connections.initH2();
@ -60,200 +69,184 @@ public class QueryPerformanceTest {
Connections.close();
}
@Test
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void jDBC() throws Exception {
Runner.run("jdbc by id", new Benchmark() {
@Override
public void run(int times) throws Exception {
for (int i = 0; i < times; i++) {
try (PreparedStatement stmt = conn.prepareStatement(QUERY)) {
stmt.setLong(1, i);
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
rs.getString(1);
}
}
}
try (Connection conn = Connections.getH2();
PreparedStatement stmt = conn.prepareStatement(QUERY)) {
stmt.setLong(1, ThreadLocalRandom.current().nextLong());
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
rs.getString(1);
}
}
});
}
}
@Test
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void jDBC2() throws Exception {
Runner.run("jdbc by name", new Benchmark() {
@Override
public void run(int times) throws Exception {
for (int i = 0; i < times; i++) {
try (PreparedStatement stmt = conn.prepareStatement(QUERY)) {
stmt.setString(1, String.valueOf(i));
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
rs.getString(1);
}
}
}
try (Connection conn = Connections.getH2();
PreparedStatement stmt = conn.prepareStatement(QUERY)) {
stmt.setString(1, String.valueOf(ThreadLocalRandom.current().nextLong()));
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
rs.getString(1);
}
}
});
}
}
@Test
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void querydsl1() throws Exception {
Runner.run("qdsl by id", new Benchmark() {
@Override
public void run(int times) throws Exception {
for (int i = 0; i < times; i++) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf);
query.from(companies).where(companies.id.eq((long) i))
.select(companies.name).fetch();
}
}
});
try (Connection conn = Connections.getH2()) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf);
query.from(companies).where(companies.id.eq((long) ThreadLocalRandom.current().nextLong()))
.select(companies.name).fetch();
}
}
@Test
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void querydsl12() throws Exception {
Runner.run("qdsl by id (iterated)", new Benchmark() {
@Override
public void run(int times) throws Exception {
for (int i = 0; i < times; i++) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf);
try (CloseableIterator<String> it = query.from(companies)
.where(companies.id.eq((long) i)).select(companies.name).iterate()) {
while (it.hasNext()) {
it.next();
}
}
try (Connection conn = Connections.getH2()) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf);
try (CloseableIterator<String> it = query.from(companies)
.where(companies.id.eq((long) ThreadLocalRandom.current().nextLong())).select(companies.name).iterate()) {
while (it.hasNext()) {
it.next();
}
}
});
}
}
@Test
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void querydsl13() throws Exception {
Runner.run("qdsl by id (result set access)", new Benchmark() {
@Override
public void run(int times) throws Exception {
for (int i = 0; i < times; i++) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf);
try (ResultSet rs = query.select(companies.name).from(companies)
.where(companies.id.eq((long) i)).getResults()) {
while (rs.next()) {
rs.getString(1);
}
}
try (Connection conn = Connections.getH2()) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf);
try (ResultSet rs = query.select(companies.name).from(companies)
.where(companies.id.eq((long) ThreadLocalRandom.current().nextLong())).getResults()) {
while (rs.next()) {
rs.getString(1);
}
}
});
}
}
@Test
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void querydsl14() throws Exception {
Runner.run("qdsl by id (no validation)", new Benchmark() {
@Override
public void run(int times) throws Exception {
for (int i = 0; i < times; i++) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf, new DefaultQueryMetadata());
query.from(companies).where(companies.id.eq((long) i))
.select(companies.name).fetch();
}
}
});
try (Connection conn = Connections.getH2()) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf, new DefaultQueryMetadata());
query.from(companies).where(companies.id.eq((long) ThreadLocalRandom.current().nextLong()))
.select(companies.name).fetch();
}
}
@Test
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void querydsl15() throws Exception {
Runner.run("qdsl by id (two cols)", new Benchmark() {
@Override
public void run(int times) throws Exception {
for (int i = 0; i < times; i++) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf);
query.from(companies).where(companies.id.eq((long) i))
.select(companies.id, companies.name).fetch();
}
}
});
try (Connection conn = Connections.getH2()) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf);
query.from(companies).where(companies.id.eq((long) ThreadLocalRandom.current().nextLong()))
.select(companies.id, companies.name).fetch();
}
}
@Test
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void querydsl2() throws Exception {
Runner.run("qdsl by name", new Benchmark() {
@Override
public void run(int times) throws Exception {
for (int i = 0; i < times; i++) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf);
query.from(companies).where(companies.name.eq(String.valueOf(i)))
.select(companies.name).fetch();
}
}
});
try (Connection conn = Connections.getH2()) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf);
query.from(companies).where(companies.name.eq(String.valueOf(ThreadLocalRandom.current().nextLong())))
.select(companies.name).fetch();
}
}
@Test
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void querydsl22() throws Exception {
Runner.run("qdsl by name (iterated)", new Benchmark() {
@Override
public void run(int times) throws Exception {
for (int i = 0; i < times; i++) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf);
try (CloseableIterator<String> it = query.from(companies)
.where(companies.name.eq(String.valueOf(i)))
.select(companies.name).iterate()) {
while (it.hasNext()) {
it.next();
}
}
try (Connection conn = Connections.getH2()) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf);
try (CloseableIterator<String> it = query.from(companies)
.where(companies.name.eq(String.valueOf(ThreadLocalRandom.current().nextLong())))
.select(companies.name).iterate()) {
while (it.hasNext()) {
it.next();
}
}
});
}
}
@Test
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void querydsl23() throws Exception {
Runner.run("qdsl by name (no validation)", new Benchmark() {
@Override
public void run(int times) throws Exception {
for (int i = 0; i < times; i++) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf, new DefaultQueryMetadata());
query.from(companies)
.where(companies.name.eq(String.valueOf(i)))
.select(companies.name).fetch();
}
}
});
try (Connection conn = Connections.getH2()) {
QCompanies companies = QCompanies.companies;
SQLQuery<?> query = new SQLQuery<Void>(conn, conf, new DefaultQueryMetadata());
query.from(companies)
.where(companies.name.eq(String.valueOf(ThreadLocalRandom.current().nextLong())))
.select(companies.name).fetch();
}
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void serialization() throws Exception {
try (Connection conn = Connections.getH2()) {
QCompanies companies = QCompanies.companies;
final QueryMetadata md = new DefaultQueryMetadata();
md.addJoin(JoinType.DEFAULT, companies);
md.addWhere(companies.id.eq(1L));
md.setProjection(companies.name);
SQLSerializer serializer = new SQLSerializer(conf);
serializer.serialize(md, false);
serializer.getConstants();
serializer.getConstantPaths();
assertNotNull(serializer.toString());
}
}
@Test
public void serialization() throws Exception {
QCompanies companies = QCompanies.companies;
final QueryMetadata md = new DefaultQueryMetadata();
md.addJoin(JoinType.DEFAULT, companies);
md.addWhere(companies.id.eq(1L));
md.setProjection(companies.name);
public void launchBenchmark() throws Exception {
Options opt = new OptionsBuilder()
.include(this.getClass().getName() + ".*")
.mode(Mode.AverageTime)
.timeUnit(TimeUnit.MICROSECONDS)
.warmupTime(TimeValue.seconds(1))
.warmupIterations(1)
.measurementTime(TimeValue.seconds(1))
.measurementIterations(3)
.threads(1)
.forks(1)
.shouldFailOnError(true)
.shouldDoGC(true)
.build();
Runner.run("ser1", new Benchmark() {
@Override
public void run(int times) throws Exception {
for (int i = 0; i < times; i++) {
SQLSerializer serializer = new SQLSerializer(conf);
serializer.serialize(md, false);
serializer.getConstants();
serializer.getConstantPaths();
assertNotNull(serializer.toString());
}
}
});
new Runner(opt).run();
}
}