Skip to content

Commit

Permalink
[misc] small performance enhancement using fastpath
Browse files Browse the repository at this point in the history
  • Loading branch information
rusher committed Sep 6, 2022
1 parent f07e232 commit 9a972b1
Show file tree
Hide file tree
Showing 15 changed files with 111 additions and 117 deletions.
5 changes: 0 additions & 5 deletions src/benchmark/java/org/mariadb/jdbc/Common.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,16 @@ public static class MyState {

@Param({"mysql", "mariadb"})
String driver;

int fetchSize;

@Setup(Level.Trial)
public void createConnections() throws Exception {

String className;
switch (driver) {
case "mysql":
className = "com.mysql.cj.jdbc.Driver";
fetchSize = Integer.MIN_VALUE;
break;
case "mariadb":
className = "org.mariadb.jdbc.Driver";
fetchSize = 1;
break;
default:
throw new RuntimeException("wrong param");
Expand Down
18 changes: 8 additions & 10 deletions src/benchmark/java/org/mariadb/jdbc/Select_1000_Rows.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,24 @@ public class Select_1000_Rows extends Common {
"select seq, 'abcdefghijabcdefghijabcdefghijaa' from seq_1_to_1000";

@Benchmark
public String[] text(MyState state) throws Throwable {
return run(state.connectionText, state.fetchSize);
public int text(MyState state) throws Throwable {
return run(state.connectionText);
}

@Benchmark
public String[] binary(MyState state) throws Throwable {
return run(state.connectionBinary, state.fetchSize);
public int binary(MyState state) throws Throwable {
return run(state.connectionBinary);
}

private String[] run(Connection con, int fetchSize) throws Throwable {
private int run(Connection con) throws Throwable {
try (PreparedStatement st = con.prepareStatement(sql)) {
st.setFetchSize(fetchSize);
ResultSet rs = st.executeQuery();
String[] res = new String[1000];
int i = 0;
while (rs.next()) {
rs.getInt(1);
res[i++] = rs.getString(2);
i = rs.getInt(1);
rs.getString(2);
}
return res;
return i;
}
}
}
11 changes: 11 additions & 0 deletions src/main/java/org/mariadb/jdbc/client/ReadableByteBuf.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ public interface ReadableByteBuf {
*/
void skip(int length);

/** Skip length encoded value */
void skipLengthEncoded();

/**
* Read Blob at current position
*
Expand Down Expand Up @@ -111,6 +114,14 @@ public interface ReadableByteBuf {
*/
int skipIdentifier();

/**
* Fast long from text parsing
*
* @param length data length
* @return long value
*/
long atoi(int length);

/**
* Read encoded length value see
* https://mariadb.com/kb/en/protocol-data-types/#length-encoded-integers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
public final class StandardReadableByteBuf implements ReadableByteBuf {

private int limit;
private byte[] buf;
public byte[] buf;
private int pos;

/**
Expand Down Expand Up @@ -57,11 +57,48 @@ public void skip(int length) {
pos += length;
}

public void skipLengthEncoded() {
int len = buf[pos++] & 0xff;
if (len < 251) {
pos += len;
} else {
switch (len) {
case 252:
pos += readUnsignedShort();
break;
case 253:
pos += readUnsignedMedium();
break;
case 254:
pos += 4 + readUnsignedInt();
break;
}
}
}

public MariaDbBlob readBlob(int length) {
pos += length;
return MariaDbBlob.safeMariaDbBlob(buf, pos - length, length);
}

public long atoi(int length) {
boolean negate = false;
int idx = 0;
long result = 0;

if (length > 0 && buf[pos] == 45) { // minus sign
negate = true;
pos++;
idx++;
}

while (idx++ < length) {
result = result * 10 + buf[pos++] - 48;
}

return (negate) ? -1 * result : result;
}

public byte getByte() {
return buf[pos];
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/mariadb/jdbc/client/result/Result.java
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ public boolean wasNull() {

@Override
public String getString(int columnIndex) throws SQLException {
return row.getValue(columnIndex, StringCodec.INSTANCE, null);
return row.getStringValue(columnIndex);
}

@Override
Expand Down
25 changes: 6 additions & 19 deletions src/main/java/org/mariadb/jdbc/codec/BinaryRowDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ public <T> T decode(Codec<T> codec, Calendar cal) throws SQLException {
return codec.decodeBinary(readBuf, length, columns[index], cal);
}

@Override
public String decodeString() throws SQLException {
return StringCodec.INSTANCE.decodeBinary(readBuf, length, columns[index], null);
}

@Override
public byte decodeByte() throws SQLException {
return ByteCodec.INSTANCE.decodeBinaryByte(readBuf, length, columns[index]);
Expand Down Expand Up @@ -119,25 +124,7 @@ public void setPosition(int newIndex) {
break;

default:
int len = this.readBuf.readUnsignedByte();
if (len < 251) {
// length is encoded on 1 bytes (is then less than 251)
this.readBuf.skip(len);
break;
}
switch (len) {
case 252:
this.readBuf.skip(this.readBuf.readUnsignedShort());
break;

case 253:
this.readBuf.skip(this.readBuf.readUnsignedMedium());
break;

case 254:
this.readBuf.skip((int) this.readBuf.readLong());
break;
}
this.readBuf.skipLengthEncoded();
break;
}
}
Expand Down
15 changes: 12 additions & 3 deletions src/main/java/org/mariadb/jdbc/codec/RowDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@
import java.util.*;
import org.mariadb.jdbc.Configuration;
import org.mariadb.jdbc.client.Column;
import org.mariadb.jdbc.client.ReadableByteBuf;
import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
import org.mariadb.jdbc.plugin.Codec;

public abstract class RowDecoder {
protected static final int NULL_LENGTH = -1;
private final Configuration conf;
protected final ReadableByteBuf readBuf = new StandardReadableByteBuf(null, 0);
protected final StandardReadableByteBuf readBuf = new StandardReadableByteBuf(null, 0);
protected final Column[] columns;

protected int length;
Expand Down Expand Up @@ -47,6 +46,8 @@ public void setRow(byte[] buf) {

public abstract int decodeInt() throws SQLException;

public abstract String decodeString() throws SQLException;

public abstract long decodeLong() throws SQLException;

public abstract float decodeFloat() throws SQLException;
Expand Down Expand Up @@ -90,7 +91,7 @@ private void checkIndexAndSetPosition(int index) throws SQLException {
String.format(
"Wrong index position. Is %s but must be in 1-%s range", index, columnCount));
}
if (readBuf.buf() == null) {
if (readBuf.buf == null) {
throw new SQLDataException("wrong row position", "22023");
}

Expand Down Expand Up @@ -145,6 +146,14 @@ public int getIntValue(int index) throws SQLException {
return decodeInt();
}

public String getStringValue(int index) throws SQLException {
checkIndexAndSetPosition(index);
if (length == NULL_LENGTH) {
return null;
}
return decodeString();
}

public long getLongValue(int index) throws SQLException {
checkIndexAndSetPosition(index);
if (length == NULL_LENGTH) {
Expand Down
25 changes: 6 additions & 19 deletions src/main/java/org/mariadb/jdbc/codec/TextRowDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public <T> T decode(Codec<T> codec, Calendar cal) throws SQLException {
return codec.decodeText(readBuf, length, columns[index], cal);
}

@Override
public String decodeString() throws SQLException {
return StringCodec.INSTANCE.decodeText(readBuf, length, columns[index], null);
}

@Override
public byte decodeByte() throws SQLException {
return ByteCodec.INSTANCE.decodeTextByte(readBuf, length, columns[index]);
Expand Down Expand Up @@ -77,25 +82,7 @@ public void setPosition(int newIndex) {
}

while (index < newIndex) {
short len = this.readBuf.readUnsignedByte();
if (len < 251) {
// length is encoded on 1 bytes (is then less than 251)
readBuf.skip(len);
} else {
switch (len) {
case 252:
readBuf.skip(readBuf.readUnsignedShort());
break;
case 253:
readBuf.skip(readBuf.readUnsignedMedium());
break;
case 254:
readBuf.skip((int) (4 + readBuf.readUnsignedInt()));
break;
case 251:
break;
}
}
this.readBuf.skipLengthEncoded();
index++;
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/mariadb/jdbc/plugin/codec/ByteCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public byte decodeTextByte(ReadableByteBuf buf, int length, Column column)
case INTEGER:
case BIGINT:
case YEAR:
result = LongCodec.parseNotEmpty(buf, length);
result = buf.atoi(length);
break;

case BIT:
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/mariadb/jdbc/plugin/codec/DateCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public Date decodeText(ReadableByteBuf buf, int length, Column column, Calendar

switch (column.getType()) {
case YEAR:
short y = (short) LongCodec.parseNotEmpty(buf, length);
short y = (short) buf.atoi(length);
if (column.getLength() == 2) {
// YEAR(2) - deprecated
if (y <= 69) {
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/org/mariadb/jdbc/plugin/codec/IntCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,16 @@ public int decodeTextInt(final ReadableByteBuf buf, final int length, final Colu
throws SQLDataException {
long result;
switch (column.getType()) {
case INTEGER:
case BIGINT:
result = buf.atoi(length);
break;

case TINYINT:
case SMALLINT:
case MEDIUMINT:
case YEAR:
return (int) LongCodec.parseNotEmpty(buf, length);

case INTEGER:
case BIGINT:
result = LongCodec.parseNotEmpty(buf, length);
break;
return (int) buf.atoi(length);

case BIT:
result = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public LocalDate decodeText(ReadableByteBuf buf, int length, Column column, Cale
int[] parts;
switch (column.getType()) {
case YEAR:
short y = (short) LongCodec.parseNotEmpty(buf, length);
short y = (short) buf.atoi(length);

if (length == 2 && column.getLength() == 2) {
// YEAR(2) - deprecated
Expand Down
31 changes: 2 additions & 29 deletions src/main/java/org/mariadb/jdbc/plugin/codec/LongCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,33 +46,6 @@ public class LongCodec implements Codec<Long> {
DataType.MEDIUMBLOB,
DataType.LONGBLOB);

/**
* Fast long from text parsing
*
* @param buf packet buffer
* @param length data length
* @return long value
*/
public static long parseNotEmpty(ReadableByteBuf buf, int length) {

boolean negate = false;
int idx = 0;
long result = 0;

if (length > 0 && buf.getByte() == 45) { // minus sign
negate = true;
buf.skip();
idx++;
}

while (idx++ < length) {
result = result * 10 + buf.readByte() - 48;
}

if (negate) result = -1 * result;
return result;
}

public String className() {
return Long.class.getName();
}
Expand Down Expand Up @@ -112,11 +85,11 @@ public long decodeTextLong(ReadableByteBuf buf, int length, Column column)
case MEDIUMINT:
case INTEGER:
case YEAR:
return parseNotEmpty(buf, length);
return buf.atoi(length);

case BIGINT:
if (column.isSigned()) {
return parseNotEmpty(buf, length);
return buf.atoi(length);
} else {
BigInteger val = new BigInteger(buf.readAscii(length));
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public short decodeTextShort(ReadableByteBuf buf, int length, Column column)
case INTEGER:
case BIGINT:
case YEAR:
result = LongCodec.parseNotEmpty(buf, length);
result = buf.atoi(length);
break;

case BIT:
Expand Down

0 comments on commit 9a972b1

Please sign in to comment.