/spring-data-mongodb-benchmarks/src/main/java/org/springframework/data/mongodb/core/ProjectionsBenchmark.java

https://github.com/spring-projects/spring-data-mongodb · Java · 180 lines · 97 code · 35 blank · 48 comment · 0 complexity · 44e5b803f34a9351c7bef0674da6f846 MD5 · raw file

  1. /*
  2. * Copyright 2017-2022 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.mongodb.core;
  17. import org.bson.Document;
  18. import org.openjdk.jmh.annotations.Benchmark;
  19. import org.openjdk.jmh.annotations.Setup;
  20. import org.openjdk.jmh.annotations.TearDown;
  21. import org.springframework.beans.factory.annotation.Value;
  22. import org.springframework.data.annotation.Id;
  23. import org.springframework.data.mongodb.core.ExecutableFindOperation.FindWithQuery;
  24. import org.springframework.data.mongodb.core.ExecutableFindOperation.TerminatingFind;
  25. import org.springframework.data.mongodb.core.mapping.Field;
  26. import org.springframework.data.mongodb.core.query.BasicQuery;
  27. import org.springframework.data.mongodb.microbenchmark.AbstractMicrobenchmark;
  28. import com.mongodb.MongoClient;
  29. import com.mongodb.ServerAddress;
  30. import com.mongodb.client.MongoCollection;
  31. /**
  32. * @author Christoph Strobl
  33. */
  34. public class ProjectionsBenchmark extends AbstractMicrobenchmark {
  35. private static final String DB_NAME = "projections-benchmark";
  36. private static final String COLLECTION_NAME = "projections";
  37. private MongoTemplate template;
  38. private MongoClient client;
  39. private MongoCollection<Document> mongoCollection;
  40. private Person source;
  41. private FindWithQuery<Person> asPerson;
  42. private FindWithQuery<DtoProjection> asDtoProjection;
  43. private FindWithQuery<ClosedProjection> asClosedProjection;
  44. private FindWithQuery<OpenProjection> asOpenProjection;
  45. private TerminatingFind<Person> asPersonWithFieldsRestriction;
  46. private Document fields = new Document("firstname", 1);
  47. @Setup
  48. public void setUp() {
  49. client = new MongoClient(new ServerAddress());
  50. template = new MongoTemplate(client, DB_NAME);
  51. source = new Person();
  52. source.firstname = "luke";
  53. source.lastname = "skywalker";
  54. source.address = new Address();
  55. source.address.street = "melenium falcon 1";
  56. source.address.city = "deathstar";
  57. template.save(source, COLLECTION_NAME);
  58. asPerson = template.query(Person.class).inCollection(COLLECTION_NAME);
  59. asDtoProjection = template.query(Person.class).inCollection(COLLECTION_NAME).as(DtoProjection.class);
  60. asClosedProjection = template.query(Person.class).inCollection(COLLECTION_NAME).as(ClosedProjection.class);
  61. asOpenProjection = template.query(Person.class).inCollection(COLLECTION_NAME).as(OpenProjection.class);
  62. asPersonWithFieldsRestriction = template.query(Person.class).inCollection(COLLECTION_NAME)
  63. .matching(new BasicQuery(new Document(), fields));
  64. mongoCollection = client.getDatabase(DB_NAME).getCollection(COLLECTION_NAME);
  65. }
  66. @TearDown
  67. public void tearDown() {
  68. client.dropDatabase(DB_NAME);
  69. client.close();
  70. }
  71. /**
  72. * Set the baseline for comparison by using the plain MongoDB java driver api without any additional fluff.
  73. *
  74. * @return
  75. */
  76. @Benchmark // DATAMONGO-1733
  77. public Object baseline() {
  78. return mongoCollection.find().first();
  79. }
  80. /**
  81. * Read into the domain type including all fields.
  82. *
  83. * @return
  84. */
  85. @Benchmark // DATAMONGO-1733
  86. public Object readIntoDomainType() {
  87. return asPerson.all();
  88. }
  89. /**
  90. * Read into the domain type but restrict query to only return one field.
  91. *
  92. * @return
  93. */
  94. @Benchmark // DATAMONGO-1733
  95. public Object readIntoDomainTypeRestrictingToOneField() {
  96. return asPersonWithFieldsRestriction.all();
  97. }
  98. /**
  99. * Read into dto projection that only needs to map one field back.
  100. *
  101. * @return
  102. */
  103. @Benchmark // DATAMONGO-1733
  104. public Object readIntoDtoProjectionWithOneField() {
  105. return asDtoProjection.all();
  106. }
  107. /**
  108. * Read into closed interface projection.
  109. *
  110. * @return
  111. */
  112. @Benchmark // DATAMONGO-1733
  113. public Object readIntoClosedProjectionWithOneField() {
  114. return asClosedProjection.all();
  115. }
  116. /**
  117. * Read into an open projection backed by the mapped domain object.
  118. *
  119. * @return
  120. */
  121. @Benchmark // DATAMONGO-1733
  122. public Object readIntoOpenProjection() {
  123. return asOpenProjection.all();
  124. }
  125. static class Person {
  126. @Id String id;
  127. String firstname;
  128. String lastname;
  129. Address address;
  130. }
  131. static class Address {
  132. String city;
  133. String street;
  134. }
  135. static class DtoProjection {
  136. @Field("firstname") String name;
  137. }
  138. static interface ClosedProjection {
  139. String getFirstname();
  140. }
  141. static interface OpenProjection {
  142. @Value("#{target.firstname}")
  143. String name();
  144. }
  145. }