Skip to content

Commit 51155f1

Browse files
authored
Updates benchmark to latest version of Helidon (#9326)
* Centralizes JSON serialization. Minor optimizations to pgclient repository implementation. Signed-off-by: Santiago Pericas-Geertsen <[email protected]> * Fixes problem in PgClientRepository.getFortunes(). Signed-off-by: Santiago Pericas-Geertsen <[email protected]> * Sets a VT factory for Hikari CP. Signed-off-by: Santiago Pericas-Geertsen <[email protected]> * Additional configuration for Hikari CP. Signed-off-by: Santiago Pericas-Geertsen <[email protected]> * Sets Helidon version to 4.1.2. Signed-off-by: Santiago Pericas-Geertsen <[email protected]> * Set content type in response. Fixes problems with JSON serialization. Signed-off-by: Santiago Pericas-Geertsen <[email protected]> --------- Signed-off-by: Santiago Pericas-Geertsen <[email protected]>
1 parent 313487b commit 51155f1

File tree

9 files changed

+177
-158
lines changed

9 files changed

+177
-158
lines changed

frameworks/Java/helidon/nima/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<parent>
2222
<groupId>io.helidon.applications</groupId>
2323
<artifactId>helidon-se</artifactId>
24-
<version>4.0.3</version>
24+
<version>4.1.2</version>
2525
<relativePath/>
2626
</parent>
2727

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package io.helidon.benchmark.nima;
2+
3+
import java.io.IOException;
4+
import java.util.Arrays;
5+
import java.util.Map;
6+
import java.util.List;
7+
8+
import com.jsoniter.output.JsonStream;
9+
import com.jsoniter.output.JsonStreamPool;
10+
import com.jsoniter.spi.JsonException;
11+
12+
public class JsonSerializer {
13+
14+
private JsonSerializer() {
15+
}
16+
17+
/**
18+
* Serialize an instance into a JSON object and return it as a byte array.
19+
*
20+
* @param obj the instance
21+
* @return the byte array
22+
*/
23+
public static byte[] serialize(Object obj) {
24+
JsonStream stream = JsonStreamPool.borrowJsonStream();
25+
try {
26+
stream.reset(null);
27+
stream.writeVal(obj.getClass(), obj);
28+
return Arrays.copyOfRange(stream.buffer().data(), 0, stream.buffer().tail());
29+
} catch (IOException e) {
30+
throw new JsonException(e);
31+
} finally {
32+
JsonStreamPool.returnJsonStream(stream);
33+
}
34+
}
35+
36+
/**
37+
* Serialize a map of strings into a JSON object and return it as a byte array.
38+
*
39+
* @param map the map
40+
* @return the byte array
41+
*/
42+
public static byte[] serialize(Map<String, String> map) {
43+
JsonStream stream = JsonStreamPool.borrowJsonStream();
44+
try {
45+
stream.reset(null);
46+
stream.writeObjectStart();
47+
map.forEach((k, v) -> {
48+
try {
49+
stream.writeObjectField(k);
50+
stream.writeVal(v);
51+
} catch (Exception e) {
52+
throw new RuntimeException(e);
53+
}
54+
});
55+
stream.writeObjectEnd();
56+
return Arrays.copyOfRange(stream.buffer().data(), 0, stream.buffer().tail());
57+
} catch (IOException e) {
58+
throw new JsonException(e);
59+
} finally {
60+
JsonStreamPool.returnJsonStream(stream);
61+
}
62+
}
63+
64+
/**
65+
* Serialize a list of objects into a JSON array and return it as a byte array.
66+
*
67+
* @param objs the list of objects
68+
* @return the byte array
69+
*/
70+
public static byte[] serialize(List<?> objs) {
71+
JsonStream stream = JsonStreamPool.borrowJsonStream();
72+
try {
73+
stream.reset(null);
74+
stream.writeArrayStart();
75+
int i = 0;
76+
int n = objs.size();
77+
for (Object obj : objs) {
78+
stream.writeVal(obj.getClass(), obj);
79+
if (i++ < n - 1) {
80+
stream.writeMore();
81+
}
82+
83+
}
84+
stream.writeArrayEnd();
85+
return Arrays.copyOfRange(stream.buffer().data(), 0, stream.buffer().tail());
86+
} catch (IOException e) {
87+
throw new JsonException(e);
88+
} finally {
89+
JsonStreamPool.returnJsonStream(stream);
90+
}
91+
}
92+
}

frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/Main.java

Lines changed: 6 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,9 @@
1616

1717
package io.helidon.benchmark.nima;
1818

19-
import java.io.IOException;
2019
import java.nio.charset.StandardCharsets;
21-
import java.util.Arrays;
2220
import java.util.logging.Logger;
2321

24-
import com.jsoniter.output.JsonStream;
25-
import com.jsoniter.output.JsonStreamPool;
26-
import com.jsoniter.spi.JsonException;
2722
import io.helidon.benchmark.nima.models.DbRepository;
2823
import io.helidon.benchmark.nima.models.HikariJdbcRepository;
2924
import io.helidon.benchmark.nima.models.PgClientRepository;
@@ -41,6 +36,8 @@
4136
import io.helidon.webserver.http.ServerRequest;
4237
import io.helidon.webserver.http.ServerResponse;
4338

39+
import static io.helidon.benchmark.nima.JsonSerializer.serialize;
40+
4441
/**
4542
* Main class of the benchmark.
4643
* Opens server on localhost:8080 and exposes {@code /plaintext} and {@code /json} endpoints adhering to the
@@ -90,29 +87,14 @@ static void routing(HttpRules rules) {
9087

9188
rules.get("/plaintext", new PlaintextHandler())
9289
.get("/json", new JsonHandler())
93-
.get("/10k", new JsonKHandler(10))
9490
.get("/fortunes", new FortuneHandler(repository))
9591
.register("/", new DbService(repository));
9692
}
9793

98-
private static byte[] serializeMsg(Message obj) {
99-
JsonStream stream = JsonStreamPool.borrowJsonStream();
100-
try {
101-
stream.reset(null);
102-
stream.writeVal(Message.class, obj);
103-
return Arrays.copyOfRange(stream.buffer().data(), 0, stream.buffer().tail());
104-
} catch (IOException e) {
105-
throw new JsonException(e);
106-
} finally {
107-
JsonStreamPool.returnJsonStream(stream);
108-
}
109-
}
110-
11194
static class PlaintextHandler implements Handler {
11295
static final Header CONTENT_TYPE = HeaderValues.createCached(HeaderNames.CONTENT_TYPE,
113-
"text/plain; charset=UTF-8");
96+
"text/plain; charset=UTF-8");
11497
static final Header CONTENT_LENGTH = HeaderValues.createCached(HeaderNames.CONTENT_LENGTH, "13");
115-
11698
private static final byte[] RESPONSE_BYTES = "Hello, World!".getBytes(StandardCharsets.UTF_8);
11799

118100
@Override
@@ -126,44 +108,16 @@ public void handle(ServerRequest req, ServerResponse res) {
126108

127109
static class JsonHandler implements Handler {
128110
private static final String MESSAGE = "Hello, World!";
129-
private static final int JSON_LENGTH = serializeMsg(new Message(MESSAGE)).length;
111+
private static final int JSON_LENGTH = serialize(new Message(MESSAGE)).length;
130112
static final Header CONTENT_LENGTH = HeaderValues.createCached(HeaderNames.CONTENT_LENGTH,
131-
String.valueOf(JSON_LENGTH));
113+
String.valueOf(JSON_LENGTH));
132114

133115
@Override
134116
public void handle(ServerRequest req, ServerResponse res) {
135117
res.header(CONTENT_LENGTH);
136118
res.header(HeaderValues.CONTENT_TYPE_JSON);
137119
res.header(Main.SERVER);
138-
res.send(serializeMsg(newMsg()));
139-
}
140-
141-
private static Message newMsg() {
142-
return new Message("Hello, World!");
143-
}
144-
}
145-
146-
static class JsonKHandler implements Handler {
147-
private final Header contentLength;
148-
private final String message;
149-
150-
JsonKHandler(int kilobytes) {
151-
this.message = "a".repeat(1024 * kilobytes);
152-
int length = serializeMsg(new Message(message)).length;
153-
this.contentLength = HeaderValues.createCached(HeaderNames.CONTENT_LENGTH,
154-
String.valueOf(length));
155-
}
156-
157-
@Override
158-
public void handle(ServerRequest req, ServerResponse res) {
159-
res.header(contentLength);
160-
res.header(HeaderValues.CONTENT_TYPE_JSON);
161-
res.header(Main.SERVER);
162-
res.send(serializeMsg(newMsg()));
163-
}
164-
165-
private Message newMsg() {
166-
return new Message(message);
120+
res.send(serialize(new Message(MESSAGE)));
167121
}
168122
}
169123

frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/DbRepository.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,16 @@
66
import java.util.concurrent.ThreadLocalRandom;
77

88
import jakarta.json.Json;
9-
import jakarta.json.JsonArray;
10-
import jakarta.json.JsonArrayBuilder;
119
import jakarta.json.JsonBuilderFactory;
12-
import jakarta.json.JsonObject;
1310

1411
public interface DbRepository {
1512

1613
JsonBuilderFactory JSON = Json.createBuilderFactory(Collections.emptyMap());
1714

18-
default World getWorld() {
19-
return getWorld(randomWorldNumber());
20-
}
21-
2215
World getWorld(int id);
2316

24-
default JsonObject getWorldAsJson(int id) {
25-
return getWorld().toJson();
26-
}
27-
2817
List<World> getWorlds(int count);
2918

30-
default JsonArray getWorldsAsJson(int count) {
31-
JsonArrayBuilder result = JSON.createArrayBuilder();
32-
for (World world : getWorlds(count)) {
33-
result.add(world.toJson());
34-
}
35-
return result.build();
36-
}
37-
3819
World updateWorld(World world);
3920

4021
List<World> updateWorlds(int count);

frameworks/Java/helidon/nima/src/main/java/io/helidon/benchmark/nima/models/HikariJdbcRepository.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import java.sql.SQLException;
88
import java.util.ArrayList;
99
import java.util.List;
10+
import java.util.concurrent.Executors;
11+
import java.util.concurrent.ThreadFactory;
1012
import java.util.logging.Logger;
1113

1214
import com.zaxxer.hikari.HikariConfig;
@@ -22,20 +24,31 @@ public class HikariJdbcRepository implements DbRepository {
2224
private final HikariConfig hikariConfig;
2325

2426
public HikariJdbcRepository(Config config) {
27+
// hikari connection configuration
2528
String url = "jdbc:postgresql://" +
2629
config.get("host").asString().orElse("tfb-database") +
2730
":" + config.get("port").asString().orElse("5432") +
2831
"/" + config.get("db").asString().orElse("hello_world");
29-
3032
hikariConfig = new HikariConfig();
3133
hikariConfig.setJdbcUrl(url);
3234
hikariConfig.setUsername(config.get("username").asString().orElse("benchmarkdbuser"));
3335
hikariConfig.setPassword(config.get("password").asString().orElse("benchmarkdbpass"));
34-
hikariConfig.addDataSourceProperty("cachePrepStmts", "true");
3536

37+
// hikari additional configuration
3638
int poolSize = config.get("sql-pool-size").asInt().orElse(64);
37-
hikariConfig.addDataSourceProperty("maximumPoolSize", poolSize);
38-
LOGGER.info("Db pool size is set to " + poolSize);
39+
hikariConfig.setMaximumPoolSize(poolSize);
40+
LOGGER.info("Hikari pool size is set to " + poolSize);
41+
ThreadFactory vtThreadFactory = Thread.ofVirtual().factory();
42+
hikariConfig.setThreadFactory(vtThreadFactory);
43+
hikariConfig.setScheduledExecutor(Executors.newScheduledThreadPool(poolSize, vtThreadFactory));
44+
LOGGER.info("Set thread factory to VTs");
45+
46+
// data source properties
47+
hikariConfig.addDataSourceProperty("cachePrepStmts","true");
48+
hikariConfig.addDataSourceProperty("prepStmtCacheSize","250");
49+
hikariConfig.addDataSourceProperty("prepStmtCacheSqlLimit","2048");
50+
hikariConfig.addDataSourceProperty("ssl", "false");
51+
hikariConfig.addDataSourceProperty("tcpKeepAlive", "true");
3952
}
4053

4154
private Connection getConnection() throws SQLException {

0 commit comments

Comments
 (0)