From f61a1e672d080fc8bcab90a2a4429f348454ebf7 Mon Sep 17 00:00:00 2001 From: Shautvast Date: Wed, 31 May 2023 20:35:17 +0200 Subject: [PATCH] ready for performance test --- demo/pom.xml | 5 + .../contiguous/demo/DemoApplication.java | 13 +- .../contiguous/demo/model/Customer.java | 4 + .../demo/repository/CustomerRepository.java | 18 +- .../contiguous/demo/rest/DemoRestApi.java | 21 ++- .../src/main/resources/application.properties | 1 - jmeter-test.jmx | 163 ++++++++++++++++++ .../contiguous/ContiguousList.java | 38 ++-- 8 files changed, 226 insertions(+), 37 deletions(-) create mode 100644 jmeter-test.jmx diff --git a/demo/pom.xml b/demo/pom.xml index a38ea52..8fb95a3 100644 --- a/demo/pom.xml +++ b/demo/pom.xml @@ -25,6 +25,11 @@ contiguous-jdbc 1.0-SNAPSHOT + + nl.sanderhautvast + contiguous-jackson + 1.0-SNAPSHOT + org.springframework.boot spring-boot-starter-web diff --git a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/DemoApplication.java b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/DemoApplication.java index 24d495c..6919b2f 100644 --- a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/DemoApplication.java +++ b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/DemoApplication.java @@ -1,6 +1,9 @@ package nl.sanderhautvast.contiguous.demo; +import com.fasterxml.jackson.databind.Module; +import com.fasterxml.jackson.databind.module.SimpleModule; import lombok.extern.slf4j.Slf4j; +import nl.sanderhautvast.contiguous.ListSerializer; import nl.sanderhautvast.contiguous.demo.repository.RandomStuffGenerator; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; @@ -40,7 +43,7 @@ public class DemoApplication { jdbcTemplate.execute("drop table if exists customers"); jdbcTemplate.execute("create table customers (name varchar(100), email varchar(100), streetname varchar(100), housenumber integer, city varchar(100), country varchar(100))"); final RandomStuffGenerator generator = new RandomStuffGenerator(); - for (int i = 0; i < 100_000; i++) { + for (int i = 0; i < 10_000; i++) { jdbcTemplate.update("insert into customers (name, email, streetname, housenumber, city, country) values(?,?,?,?,?,?)", ps -> { String firstName = generator.generateFirstName(); @@ -57,6 +60,14 @@ public class DemoApplication { }; } + @Bean + public Module jacksonModule() { + final SimpleModule module = new SimpleModule("contiguous_module"); + module.addSerializer(new ListSerializer()); + return module; + } + + @Bean public JdbcTemplate jdbcTemplate() { return new JdbcTemplate(datasource()); diff --git a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/model/Customer.java b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/model/Customer.java index 7c8bde2..a67c23c 100644 --- a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/model/Customer.java +++ b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/model/Customer.java @@ -1,10 +1,14 @@ package nl.sanderhautvast.contiguous.demo.model; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; @Data @Builder +@NoArgsConstructor +@AllArgsConstructor public class Customer { String name; String email; diff --git a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/repository/CustomerRepository.java b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/repository/CustomerRepository.java index 7354995..b5bfbda 100644 --- a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/repository/CustomerRepository.java +++ b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/repository/CustomerRepository.java @@ -9,6 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository @Slf4j public class CustomerRepository { @@ -21,7 +23,21 @@ public class CustomerRepository { } public ContiguousList getAllCustomers() { - return jdbcTemplate.query("select * from customers limit 5", rs -> { + return jdbcTemplate.query("select * from customers limit 10000", rs -> { + return JdbcResults.toList(rs, Customer.class); + }); + } + + public List getAllCustomersTraditional() { + return jdbcTemplate.query("select * from customers", (rs, rowNum) -> new Customer( + rs.getString("name"),rs.getString("email"), + rs.getString("streetname"), rs.getInt("housenumber"), + rs.getString("city"), rs.getString("country") + )); + } + + public List getAllCustomersHybrid() { + return jdbcTemplate.query("select * from customers", rs -> { return JdbcResults.toList(rs, Customer.class); }); } diff --git a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/rest/DemoRestApi.java b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/rest/DemoRestApi.java index f4fa1e2..c6d83ef 100644 --- a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/rest/DemoRestApi.java +++ b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/rest/DemoRestApi.java @@ -22,14 +22,17 @@ public class DemoRestApi { } @GetMapping(value = "/api/customers", produces = "application/json") - public List getCustomers() { - try { - ContiguousList customers = customerRepository.getAllCustomers(); - log.info("customers {}", customers.size()); - return customers; - } catch (Exception e) { - log.error("Error", e); - throw new RuntimeException(e); - } + public ContiguousList getCustomers() { + return customerRepository.getAllCustomers(); + } + + @GetMapping(value = "/api/customers/traditional", produces = "application/json") + public List getCustomersTraditional() { + return customerRepository.getAllCustomersTraditional(); + } + + @GetMapping(value = "/api/customers/hybrid", produces = "application/json") + public List getCustomersHybrid() { + return customerRepository.getAllCustomersHybrid(); } } diff --git a/demo/src/main/resources/application.properties b/demo/src/main/resources/application.properties index 03a223e..0b382d9 100644 --- a/demo/src/main/resources/application.properties +++ b/demo/src/main/resources/application.properties @@ -1,4 +1,3 @@ -logging.level.org.springframework=ERROR spring.jpa.hibernate.ddl-auto=none spring.datasource.driverClass=org.postgresql.Driver spring.datasource.url=jdbc:postgresql://localhost:5432/postgres diff --git a/jmeter-test.jmx b/jmeter-test.jmx new file mode 100644 index 0000000..b799a2d --- /dev/null +++ b/jmeter-test.jmx @@ -0,0 +1,163 @@ + + + + + + false + true + false + + + + + + + + continue + + false + 100 + + 1 + 1 + false + + + true + + + + + + + localhost + 8080 + http + + /api/customers + GET + true + false + true + false + + + + + + + + + + localhost + 8080 + http + + api/customers/traditional + GET + true + false + true + false + + + + + + + + + + localhost + 8080 + http + + api/customers/hybrid + GET + true + false + true + false + + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + + diff --git a/lib/src/main/java/nl/sanderhautvast/contiguous/ContiguousList.java b/lib/src/main/java/nl/sanderhautvast/contiguous/ContiguousList.java index 763bc69..25fce45 100644 --- a/lib/src/main/java/nl/sanderhautvast/contiguous/ContiguousList.java +++ b/lib/src/main/java/nl/sanderhautvast/contiguous/ContiguousList.java @@ -56,11 +56,11 @@ public class ContiguousList extends NotImplementedList implements List /* * storage for dehydated objects */ - private ByteBuffer data = ByteBuffer.allocate(32); + private ByteBuffer data = ByteBuffer.allocate(4096);//TODO create constructor with capacity private int bufferPosition; - private int[] elementIndices = new int[10]; // avoids autoboxing. Could also use standard ArrayList though + private ArrayList elementIndices = new ArrayList<>(); // avoids autoboxing. Could also use standard ArrayList though // is there a standard lib IntList?? private int size; @@ -69,11 +69,7 @@ public class ContiguousList extends NotImplementedList implements List public ContiguousList(Class type) { inspectType(type); - elementIndices[0] = 0; // index of first element - } - - public Class getElementType() { - return rootHandler.getType(); + elementIndices.add(0); // index of first element } /* @@ -136,13 +132,7 @@ public class ContiguousList extends NotImplementedList implements List return false; } storePropertyData(element, rootHandler); - size += 1; - - // keep track of where the objects are stored - if (elementIndices.length < size + 1) { - this.elementIndices = Arrays.copyOf(this.elementIndices, this.elementIndices.length * 2); - } - elementIndices[size] = bufferPosition; + extend(); return true; } @@ -189,7 +179,7 @@ public class ContiguousList extends NotImplementedList implements List if (index < 0 || index >= size) { throw new IndexOutOfBoundsException("index <0 or >" + size); } - data.position(elementIndices[index]); + data.position(elementIndices.get(index)); try { if (rootHandler instanceof BuiltinTypeHandler) { Object read = ValueReader.read(data); @@ -278,14 +268,14 @@ public class ContiguousList extends NotImplementedList implements List if (index < 0 || index >= size) { throw new IndexOutOfBoundsException("index <0 or >" + size); } - data.position(elementIndices[index]); + data.position(elementIndices.get(index)); if (rootHandler instanceof BuiltinTypeHandler) { BuiltinTypeHandler handler = (BuiltinTypeHandler) rootHandler; return getValue(handler); } // create a new instance of the list element type - StringBuilder s = new StringBuilder(); + StringBuilder s = new StringBuilder(300); s.append("{"); copyDataIntoStringBuilder(s, (CompoundTypeHandler) rootHandler); s.append("}"); @@ -303,7 +293,7 @@ public class ContiguousList extends NotImplementedList implements List } private static String quote(String out) { - StringBuilder s = new StringBuilder(); + StringBuilder s = new StringBuilder(out.length() + 2); out = s.append("\"").append(out).append("\"").toString(); return out; } @@ -315,9 +305,9 @@ public class ContiguousList extends NotImplementedList implements List compoundType.getProperties().forEach(property -> { if (property instanceof BuiltinTypeHandler) { BuiltinTypeHandler typeHandler = (BuiltinTypeHandler) property; - String name = typeHandler.getName(); - String value = getValue(typeHandler); - s.append(quote(name)).append(": ").append(value); + s.append(quote(typeHandler.getName())) + .append(": ") + .append(getValue(typeHandler)); } else { CompoundTypeHandler p = (CompoundTypeHandler) property; s.append(p.getName()).append(":{"); @@ -608,16 +598,14 @@ public class ContiguousList extends NotImplementedList implements List // used by SetterIterator void extend() { size += 1; + // keep track of index of element in data + elementIndices.add(bufferPosition); } byte[] getData() { return Arrays.copyOfRange(data.array(), 0, bufferPosition); } - int[] getElementIndices() { - return Arrays.copyOfRange(elementIndices, 0, size + 1); - } - private void ensureFree(int length) { while (bufferPosition + length > data.capacity()) { byte[] bytes = this.data.array();