Permalink
Browse files

perf: short circuit Oid.BOOL in getBoolean (#745)

The BE sends "t" of "f" for Oid.BOOL so there is no need to fall in getString
which execute again checkResultSet(), decode the byte and trim the returned String.

All of this can be avoided and get a performance benefit.
  • Loading branch information...
jorsol authored and vlsi committed Feb 12, 2017
1 parent 43e6505 commit e69e4a1d5502319bc810e0e4529611ba52ea386c
@@ -1942,8 +1942,13 @@ public boolean getBoolean(int columnIndex) throws SQLException {
return false; // SQL NULL
}
int col = columnIndex - 1;
if (Oid.BOOL == fields[col].getOID()) {
final byte[] v = this_row[col];
return (1 == v.length) && (116 == v[0]); // 116 = 't'
}
if (isBinary(columnIndex)) {
int col = columnIndex - 1;
return BooleanTypeUtil.castToBoolean(readDoubleValue(this_row[col], fields[col].getOID(), "boolean"));
}
@@ -42,10 +42,6 @@ POSSIBILITY OF SUCH DAMAGE.
<description>PostgreSQL JDBC Driver - benchmarks</description>
<url>https://github.com/pgjdbc/pgjdbc</url>
<prerequisites>
<maven>3.0</maven>
</prerequisites>
<dependencies>
<dependency>
<groupId>org.openjdk.jmh</groupId>
@@ -67,7 +63,7 @@ POSSIBILITY OF SUCH DAMAGE.
</dependencies>
<properties>
<jmh.version>1.12</jmh.version>
<jmh.version>1.17.4</jmh.version>
<uberjar.name>benchmarks</uberjar.name>
<current.jdk>1.8</current.jdk>
<javac.target>${current.jdk}</javac.target>
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2017, PostgreSQL Global Development Group
* See the LICENSE file in the project root for more information.
*/
package org.postgresql.benchmark.statement;
import org.postgresql.util.ConnectionUtil;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
/**
* Benchmark to test performance of ResultSet.getBoolean() method.
*
* @author jorsol
*/
@Fork(value = 1, jvmArgsPrepend = "-Xmx128m")
@Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
@Warmup(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS)
@State(Scope.Thread)
@Threads(1)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class ProcessBoolean {
private Connection connection;
private PreparedStatement ps;
private ResultSet rs;
@Param({"5", "10", "50", "100", "10000"})
public int rowsize;
@Param({"0", "10", "50", "100"})
private int tokens;
@Setup(Level.Trial)
public void setUp() throws SQLException {
Properties props = ConnectionUtil.getProperties();
connection = DriverManager.getConnection(ConnectionUtil.getURL(), props);
ps = connection.prepareStatement("select (random() > 0.5) from generate_series(1, ?)",
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ps.setInt(1, rowsize);
rs = ps.executeQuery();
}
@TearDown(Level.Trial)
public void tearDown() throws SQLException {
rs.close();
ps.close();
connection.close();
}
@Benchmark
public void getBoolean(Blackhole b) throws SQLException {
Blackhole.consumeCPU(tokens);
rs.first();
while (rs.next()) {
b.consume(rs.getBoolean(1));
}
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(ProcessBoolean.class.getSimpleName())
.detectJvmArgs()
.build();
new Runner(opt).run();
}
}
@@ -54,6 +54,7 @@
STRING,
TIMESTAMP,
TIMESTAMPTZ,
BOOL
}
public enum ColumnIndexType {
@@ -132,6 +133,8 @@ public void setUp() throws SQLException {
sb.append("localtimestamp");
} else if (type == FieldType.TIMESTAMPTZ) {
sb.append("current_timestamp");
} else if (type == FieldType.BOOL) {
sb.append("TRUE");
}
String columnName = "c" + String.valueOf(System.currentTimeMillis()) + String.valueOf(i);
columnNames[i] = columnName;
@@ -190,6 +193,8 @@ private void getByIndex(Blackhole b, ResultSet rs, int i) throws SQLException {
b.consume(rs.getTimestamp(i));
} else if (type == FieldType.TIMESTAMPTZ) {
b.consume(rs.getTimestamp(i));
} else if (type == FieldType.BOOL) {
b.consume(rs.getBoolean(i));
}
}
@@ -208,6 +213,8 @@ private void getByName(Blackhole b, ResultSet rs, String i) throws SQLException
b.consume(rs.getTimestamp(i));
} else if (type == FieldType.TIMESTAMPTZ) {
b.consume(rs.getTimestamp(i));
} else if (type == FieldType.BOOL) {
b.consume(rs.getBoolean(i));
}
}

0 comments on commit e69e4a1

Please sign in to comment.