Skip to content

Commit de411cc

Browse files
authored
Merge pull request #763 from zhicwu/benchmarking
Benchmarking
2 parents a401726 + 395bc03 commit de411cc

29 files changed

Lines changed: 1233 additions & 609 deletions

.github/workflows/analysis.yml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,6 @@ jobs:
5353
path: ~/.m2
5454
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
5555
restore-keys: ${{ runner.os }}-m2
56-
- name: Check style and spell
57-
uses: zhicwu/checkstyle-action@master
58-
with:
59-
github_token: ${{ secrets.GITHUB_TOKEN }}
60-
reporter: 'github-pr-check'
61-
# added,diff_context,file,nofilter
62-
filter_mode: 'added'
63-
if: github.event_name == 'pull_request_target' || github.event.inputs.pr != ''
64-
continue-on-error: true
6556
- name: Update sonar config
6657
run: |
6758
sed -i -e 's|^\(.*<sonar.projectKey>\).*\(</sonar.projectKey>\)$|\1ClickHouse_clickhouse-jdbc\2|' \

.github/workflows/benchmark.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ jobs:
6161
run: |
6262
mvn --batch-mode --update-snapshots -q -DskipTests install
6363
cd clickhouse-benchmark
64-
java -DclickhouseVersion="21.8" -jar target/benchmarks.jar -rf text -p client=clickhouse-jdbc Basic
64+
java -DclickhouseVersion="21.8" -jar target/benchmarks.jar -rf text \
65+
-p client=clickhouse-http-jdbc -p type=default Basic
6566
echo "BENCHMARK_REPORT<<EOF" >> $GITHUB_ENV
6667
cat jmh-result.text >> $GITHUB_ENV
6768
echo "EOF" >> $GITHUB_ENV
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.clickhouse.benchmark.jdbc;
2+
3+
import java.sql.ResultSet;
4+
import java.sql.SQLException;
5+
6+
import org.openjdk.jmh.infra.Blackhole;
7+
8+
@FunctionalInterface
9+
public interface ConsumeValueFunction {
10+
void consume(Blackhole blackhole, ResultSet rs, int columnIndex) throws SQLException;
11+
}

clickhouse-benchmark/src/main/java/com/clickhouse/benchmark/jdbc/DriverState.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.sql.SQLException;
66
import java.sql.Statement;
77
import java.util.Properties;
8+
89
import org.openjdk.jmh.annotations.Level;
910
import org.openjdk.jmh.annotations.Param;
1011
import org.openjdk.jmh.annotations.Scope;
@@ -18,7 +19,7 @@
1819
@State(Scope.Thread)
1920
public class DriverState extends BaseState {
2021
@Param(value = { "clickhouse4j", "clickhouse-http-jdbc", "clickhouse-grpc-jdbc", "clickhouse-jdbc",
21-
"clickhouse-native-jdbc-shaded", "mariadb-java-client", "mysql-connector-java", "postgresql-jdbc" })
22+
"clickhouse-native-jdbc", "mariadb-java-client", "mysql-connector-java", "postgresql-jdbc" })
2223
private String client;
2324

2425
@Param(value = { Constants.REUSE_CONNECTION, Constants.NEW_CONNECTION })
@@ -27,6 +28,9 @@ public class DriverState extends BaseState {
2728
@Param(value = { Constants.NORMAL_STATEMENT, Constants.PREPARED_STATEMENT })
2829
private String statement;
2930

31+
@Param(value = { "default", "string", "object" })
32+
private String type;
33+
3034
private Driver driver;
3135
private String url;
3236
private Connection conn;
@@ -113,4 +117,16 @@ public Connection getConnection() throws SQLException {
113117
public boolean usePreparedStatement() {
114118
return Constants.PREPARED_STATEMENT.equalsIgnoreCase(this.statement);
115119
}
120+
121+
public ConsumeValueFunction getConsumeFunction(ConsumeValueFunction defaultFunc) {
122+
if ("string".equals(type)) {
123+
return (b, r, i) -> b.consume(r.getString(i));
124+
} else if ("object".equals(type)) {
125+
return (b, r, i) -> b.consume(r.getObject(i));
126+
} else if (defaultFunc == null) {
127+
return (b, r, i) -> b.consume(i);
128+
} else {
129+
return defaultFunc;
130+
}
131+
}
116132
}

clickhouse-benchmark/src/main/java/com/clickhouse/benchmark/jdbc/JdbcDriver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public enum JdbcDriver {
1818
"jdbc:clickhouse://%s:%s/%s?ssl=false&user=%s&password=%s&use_server_time_zone=false&use_time_zone=UTC&compress=%s",
1919
Constants.HTTP_PORT),
2020
// ClickHouse Native JDBC Driver
21-
ClickhouseNativeJdbcShaded("com.github.housepower.jdbc.ClickHouseDriver",
21+
ClickhouseNativeJdbc("com.github.housepower.jdbc.ClickHouseDriver",
2222
"jdbc:clickhouse://%s:%s/%s?ssl=false&user=%s&password=%s&use_server_time_zone=false&use_time_zone=UTC&compress=%s",
2323
Constants.NATIVE_PORT),
2424

clickhouse-benchmark/src/main/java/com/clickhouse/benchmark/jdbc/Query.java

Lines changed: 93 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,76 +7,151 @@
77

88
public class Query extends DriverBenchmark {
99
@Benchmark
10-
public void selectDateTime32Rows(Blackhole blackhole, DriverState state) throws Throwable {
10+
public void selectArrayOfInts(Blackhole blackhole, DriverState state) throws Throwable {
1111
int num = state.getRandomNumber();
1212
int rows = state.getSampleSize() + num;
13+
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getArray(i)));
1314
try (Statement stmt = executeQuery(state,
14-
"select toDateTime32(1613826920 + number) as d from system.numbers limit ?", rows)) {
15+
"select range(100, number % 600) as v from numbers(?)", rows)) {
1516
ResultSet rs = stmt.getResultSet();
1617
while (rs.next()) {
17-
blackhole.consume(rs.getTimestamp(1));
18+
func.consume(blackhole, rs, 1);
1819
}
1920
}
2021
}
2122

2223
@Benchmark
23-
public void selectDateTime64Rows(Blackhole blackhole, DriverState state) throws Throwable {
24+
public void selectMapOfInts(Blackhole blackhole, DriverState state) throws Throwable {
2425
int num = state.getRandomNumber();
2526
int rows = state.getSampleSize() + num;
27+
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getObject(i)));
2628
try (Statement stmt = executeQuery(state,
27-
"select toDateTime64(1613826920 + number / 1000000000, 9) as d from system.numbers limit ?", rows)) {
29+
"select cast((arrayMap(x->x+1000, range(1, number % 100)), arrayMap(x->x+10000, range(1, number %100))) as Map(Int32, Int32)) as v from numbers(?)",
30+
rows)) {
2831
ResultSet rs = stmt.getResultSet();
2932
while (rs.next()) {
30-
blackhole.consume(rs.getTimestamp(1));
33+
func.consume(blackhole, rs, 1);
3134
}
3235
}
3336
}
3437

3538
@Benchmark
36-
public void selectDateTime64ObjectRows(Blackhole blackhole, DriverState state) throws Throwable {
39+
public void selectTupleOfInts(Blackhole blackhole, DriverState state) throws Throwable {
3740
int num = state.getRandomNumber();
3841
int rows = state.getSampleSize() + num;
42+
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getArray(i)));
3943
try (Statement stmt = executeQuery(state,
40-
"select toDateTime64(1613826920 + number / 1000000000, 9) as d from system.numbers limit ?", rows)) {
44+
"select tuple(range(100, number % 600)) as v from numbers(?)", rows)) {
4145
ResultSet rs = stmt.getResultSet();
4246
while (rs.next()) {
43-
blackhole.consume(rs.getObject(1));
47+
func.consume(blackhole, rs, 1);
4448
}
4549
}
4650
}
4751

4852
@Benchmark
49-
public void selectInt32Rows(Blackhole blackhole, DriverState state) throws Throwable {
53+
public void selectDateTime32(Blackhole blackhole, DriverState state) throws Throwable {
5054
int num = state.getRandomNumber();
5155
int rows = state.getSampleSize() + num;
52-
try (Statement stmt = executeQuery(state, "select toInt32(number) from system.numbers limit ?", rows)) {
56+
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getTimestamp(i)));
57+
try (Statement stmt = executeQuery(state,
58+
"select toDateTime32(1613826920 + number) as v from numbers(?)", rows)) {
59+
ResultSet rs = stmt.getResultSet();
60+
while (rs.next()) {
61+
func.consume(blackhole, rs, 1);
62+
}
63+
}
64+
}
65+
66+
@Benchmark
67+
public void selectDateTime64(Blackhole blackhole, DriverState state) throws Throwable {
68+
int num = state.getRandomNumber();
69+
int rows = state.getSampleSize() + num;
70+
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getTimestamp(i)));
71+
try (Statement stmt = executeQuery(state,
72+
"select toDateTime64(1613826920 + number / 1000000000, 9) as v from numbers(?)", rows)) {
73+
ResultSet rs = stmt.getResultSet();
74+
while (rs.next()) {
75+
func.consume(blackhole, rs, 1);
76+
}
77+
}
78+
}
79+
80+
@Benchmark
81+
public void selectInt8(Blackhole blackhole, DriverState state) throws Throwable {
82+
int num = state.getRandomNumber();
83+
int rows = state.getSampleSize() + num;
84+
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getByte(i)));
85+
try (Statement stmt = executeQuery(state, "select toInt8(number % 256) as v from numbers(?)", rows)) {
86+
ResultSet rs = stmt.getResultSet();
87+
while (rs.next()) {
88+
func.consume(blackhole, rs, 1);
89+
}
90+
}
91+
}
92+
93+
@Benchmark
94+
public void selectUInt8(Blackhole blackhole, DriverState state) throws Throwable {
95+
int num = state.getRandomNumber();
96+
int rows = state.getSampleSize() + num;
97+
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getShort(i)));
98+
try (Statement stmt = executeQuery(state, "select toUInt8(number % 256) as v from numbers(?)", rows)) {
99+
ResultSet rs = stmt.getResultSet();
100+
while (rs.next()) {
101+
func.consume(blackhole, rs, 1);
102+
}
103+
}
104+
}
105+
106+
@Benchmark
107+
public void selectInt32(Blackhole blackhole, DriverState state) throws Throwable {
108+
int num = state.getRandomNumber();
109+
int rows = state.getSampleSize() + num;
110+
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getInt(i)));
111+
try (Statement stmt = executeQuery(state, "select toInt32(number) as v from numbers(?)", rows)) {
112+
ResultSet rs = stmt.getResultSet();
113+
while (rs.next()) {
114+
func.consume(blackhole, rs, 1);
115+
}
116+
}
117+
}
118+
119+
@Benchmark
120+
public void selectString(Blackhole blackhole, DriverState state) throws Throwable {
121+
int num = state.getRandomNumber();
122+
int rows = state.getSampleSize() + num;
123+
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getString(i)));
124+
try (Statement stmt = executeQuery(state, "select toString(number/3) as v from numbers(?)", rows)) {
53125
ResultSet rs = stmt.getResultSet();
54126
while (rs.next()) {
55-
blackhole.consume(rs.getInt(1));
127+
func.consume(blackhole, rs, 1);
56128
}
57129
}
58130
}
59131

60132
@Benchmark
61-
public void selectStringRows(Blackhole blackhole, DriverState state) throws Throwable {
133+
public void selectUInt64(Blackhole blackhole, DriverState state) throws Throwable {
62134
int num = state.getRandomNumber();
63135
int rows = state.getSampleSize() + num;
64-
try (Statement stmt = executeQuery(state, "select toString(number) as s from system.numbers limit ?", rows)) {
136+
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getLong(i)));
137+
try (Statement stmt = executeQuery(state, "select number as v from numbers(?)", rows)) {
65138
ResultSet rs = stmt.getResultSet();
66139
while (rs.next()) {
67-
blackhole.consume(rs.getString(1));
140+
func.consume(blackhole, rs, 1);
68141
}
69142
}
70143
}
71144

72145
@Benchmark
73-
public void selectUInt64Rows(Blackhole blackhole, DriverState state) throws Throwable {
146+
public void selectDecimal64(Blackhole blackhole, DriverState state) throws Throwable {
74147
int num = state.getRandomNumber();
75148
int rows = state.getSampleSize() + num;
76-
try (Statement stmt = executeQuery(state, "select * from system.numbers limit ?", rows)) {
149+
ConsumeValueFunction func = state.getConsumeFunction((b, r, i) -> b.consume(r.getBigDecimal(i)));
150+
try (Statement stmt = executeQuery(state, "select toDecimal64(number + number / 10000, 4) as v from numbers(?)",
151+
rows)) {
77152
ResultSet rs = stmt.getResultSet();
78153
while (rs.next()) {
79-
blackhole.consume(rs.getLong(1));
154+
func.consume(blackhole, rs, 1);
80155
}
81156
}
82157
}

clickhouse-client/src/main/java/com/clickhouse/client/ClickHouseChecker.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,27 @@ public static long between(long value, long minValue, long maxValue) {
5151
return between(value, DEFAULT_NAME, minValue, maxValue);
5252
}
5353

54+
/**
55+
* Checks if the given {@code value} is between {@code minValue} and
56+
* {@code maxValue} inclusive and throws a customized
57+
* {@link IllegalArgumentException} if it is NOT.
58+
*
59+
* @param value the value to check
60+
* @param name name of the value
61+
* @param minValue minimum value to compare with
62+
* @param maxValue maximum value to compare with
63+
* @return the exact same value
64+
* @throws IllegalArgumentException if the {@code value} is NOT between
65+
* {@code minValue} and {@code maxValue}
66+
*/
67+
public static int between(byte value, String name, byte minValue, byte maxValue) {
68+
if (value < minValue || value > maxValue) {
69+
throw newException(ERR_SHOULD_BETWEEN, name, value, minValue, maxValue);
70+
}
71+
72+
return value;
73+
}
74+
5475
/**
5576
* Checks if the given {@code value} is between {@code minValue} and
5677
* {@code maxValue} inclusive and throws a customized

clickhouse-client/src/main/java/com/clickhouse/client/ClickHouseDataProcessor.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.clickhouse.client;
22

33
import java.io.IOException;
4-
import java.io.InputStream;
54
import java.io.OutputStream;
65
import java.util.ArrayList;
76
import java.util.Collections;
@@ -34,7 +33,7 @@ protected static <T extends ClickHouseValue> void buildMappings(
3433
}
3534

3635
protected final ClickHouseConfig config;
37-
protected final InputStream input;
36+
protected final ClickHouseInputStream input;
3837
protected final OutputStream output;
3938
protected final List<ClickHouseColumn> columns;
4039
protected final Map<String, Object> settings;
@@ -60,7 +59,7 @@ protected static <T extends ClickHouseValue> void buildMappings(
6059
* @param settings nullable settings
6160
* @throws IOException when failed to read columns from input stream
6261
*/
63-
protected ClickHouseDataProcessor(ClickHouseConfig config, InputStream input, OutputStream output,
62+
protected ClickHouseDataProcessor(ClickHouseConfig config, ClickHouseInputStream input, OutputStream output,
6463
List<ClickHouseColumn> columns, Map<String, Object> settings) throws IOException {
6564
this.config = ClickHouseChecker.nonNull(config, "config");
6665
if (input == null && output == null) {

clickhouse-client/src/main/java/com/clickhouse/client/ClickHouseDataStreamFactory.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.clickhouse.client;
22

33
import java.io.IOException;
4-
import java.io.InputStream;
54
import java.io.OutputStream;
65
import java.util.List;
76
import java.util.Map;
@@ -40,8 +39,8 @@ public static ClickHouseDataStreamFactory getInstance() {
4039
* @return data processor
4140
* @throws IOException when failed to read columns from input stream
4241
*/
43-
public ClickHouseDataProcessor getProcessor(ClickHouseConfig config, InputStream input, OutputStream output,
44-
Map<String, Object> settings, List<ClickHouseColumn> columns) throws IOException {
42+
public ClickHouseDataProcessor getProcessor(ClickHouseConfig config, ClickHouseInputStream input,
43+
OutputStream output, Map<String, Object> settings, List<ClickHouseColumn> columns) throws IOException {
4544
ClickHouseFormat format = ClickHouseChecker.nonNull(config, "config").getFormat();
4645
ClickHouseDataProcessor processor;
4746
if (ClickHouseFormat.RowBinary == format || ClickHouseFormat.RowBinaryWithNamesAndTypes == format) {

clickhouse-client/src/main/java/com/clickhouse/client/ClickHouseDeserializer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.clickhouse.client;
22

33
import java.io.IOException;
4-
import java.io.InputStream;
54

65
/**
76
* Functional interface for deserialization.
@@ -19,5 +18,6 @@ public interface ClickHouseDeserializer<T extends ClickHouseValue> {
1918
* @return deserialized value which might be the same instance as {@code ref}
2019
* @throws IOException when failed to read data from input stream
2120
*/
22-
T deserialize(T ref, ClickHouseConfig config, ClickHouseColumn column, InputStream input) throws IOException;
21+
T deserialize(T ref, ClickHouseConfig config, ClickHouseColumn column, ClickHouseInputStream input)
22+
throws IOException;
2323
}

0 commit comments

Comments
 (0)