Skip to content
Permalink
Browse files
Re-add benchmarks module
JMH license is GPL With Classpath-Exception, so it does not require
to license user-written code under GPL.
  • Loading branch information
vlsi committed Apr 1, 2020
1 parent d2e4f58 commit 409bd25a576afab463857d0ada7c7fc86b97560f
Showing 23 changed files with 2,324 additions and 0 deletions.
@@ -0,0 +1,10 @@
Benchmarks for PostgreSQL JDBC Driver
=====================================

Usage
-----

See https://github.com/melix/jmh-gradle-plugin

1. Build the benchmarks via `../gradlew jmhJar`
1. Run the required benchmarks via `java -jar build/libs/benchmarks-42.3.0-SNAPSHOT-jmh.jar ...`
@@ -0,0 +1,32 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
plugins {
id("me.champeau.gradle.jmh")
}

dependencies {
// Make jmhCompileClasspath resolvable
@Suppress("DEPRECATION")
jmhCompileClasspath(platform(project(":bom")))
jmh(project(":postgresql"))
// jmh("com.google.guava:guava")
// jmh("org.codehaus.janino:commons-compiler")
jmh("org.openjdk.jmh:jmh-core")
jmh("org.openjdk.jmh:jmh-generator-annprocess")
}

// See https://github.com/melix/jmh-gradle-plugin
@@ -0,0 +1,3 @@
# Do not publish the jar
# It adds little value, however it requires effort to maintain license clearance
nexus.publish=false
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2004, PostgreSQL Global Development Group
* See the LICENSE file in the project root for more information.
*/

package org.postgresql.benchmark.connection;

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.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.profile.GCProfiler;
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.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

/**
* Tests the time and memory required to create a connection. Note: due to TCP socket's turning into
* TIME_WAIT state on close, it is rather hard to test lots of connection creations, so only 50
* iterations are performed.
*
* <p>To run this and other benchmarks (you can run the class from within IDE):
*
* <blockquote> <code>mvn package &amp;&amp; java -classpath postgresql-driver.jar:target/benchmarks.jar
* -Duser=postgres -Dpassword=postgres -Dport=5433 -wi 10 -i 10 -f 1</code> </blockquote>
*
* <p>To run with profiling:
*
* <blockquote> <code>java -classpath postgresql-driver.jar:target/benchmarks.jar -prof gc -f 1 -wi
* 10 -i 10</code> </blockquote>
*/
@Fork(1)
@Measurement(iterations = 50)
@Warmup(iterations = 10)
@State(Scope.Thread)
@Threads(1)
@BenchmarkMode(Mode.SingleShotTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class FinalizeConnection {
private Properties connectionProperties;
private String connectionUrl;
private Driver driver;

@Setup(Level.Trial)
public void setUp() throws SQLException {
Properties props = ConnectionUtil.getProperties();

connectionProperties = props;
connectionUrl = ConnectionUtil.getURL();
driver = DriverManager.getDriver(connectionUrl);
}

@Benchmark
public void baseline() throws SQLException {
}

@Benchmark
public Connection createAndClose() throws SQLException {
Connection connection = driver.connect(connectionUrl, connectionProperties);
connection.close();
return connection;
}

public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(FinalizeConnection.class.getSimpleName())
.addProfiler(GCProfiler.class)
.detectJvmArgs()
.build();

new Runner(opt).run();
}
}
@@ -0,0 +1,107 @@
/*
* Copyright (c) 2017, PostgreSQL Global Development Group
* See the LICENSE file in the project root for more information.
*/

package org.postgresql.benchmark.encoding;

import org.postgresql.core.Encoding;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
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.Threads;
import org.openjdk.jmh.annotations.Warmup;
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.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.concurrent.TimeUnit;

/**
* Tests the performance of UTF-8 decoding. UTF-8 is used a lot, so we need to know the performance
*/
@Fork(value = 5, jvmArgsPrepend = "-Xmx128m")
@Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
@State(Scope.Thread)
@Threads(1)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class UTF8Decoding {

@Param({"1", "5", "10", "50", "100"})
public int length;

private byte[] source;
private CharsetDecoder decoder;
private Encoding encoding;
private CharBuffer buf;
private static final Charset UTF_8 = Charset.forName("UTF-8");

@Setup
public void setup() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append("Hello мир,");
}
source = sb.toString().getBytes(UTF_8);
decoder = UTF_8.newDecoder();
encoding = Encoding.getJVMEncoding("UTF-8");
buf = CharBuffer.allocate(10240);
}

@Benchmark
public char[] utilsDecodeUTF8_old() {
CharBuffer buf = UTF_8.decode(ByteBuffer.wrap(source));
char[] c = new char[buf.limit()];
buf.get(c, 0, buf.limit());
return c;
}

@Benchmark
public String encodingDecodeUTF8_current() throws IOException {
return encoding.decode(source, 0, source.length);
}

@Benchmark
public String string_string() throws UnsupportedEncodingException {
return new String(source, 0, source.length, "UTF-8");
}

@Benchmark
public String string_charset() {
return new String(source, 0, source.length, UTF_8);
}

@Benchmark
public Object decoder_byteBufferReuse() throws CharacterCodingException {
buf.clear();
return decoder.decode(ByteBuffer.wrap(source), buf, true);
}

public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(UTF8Decoding.class.getSimpleName())
//.addProfiler(GCProfiler.class)
.detectJvmArgs()
.build();

new Runner(opt).run();
}
}
@@ -0,0 +1,104 @@
/*
* Copyright (c) 2004, PostgreSQL Global Development Group
* See the LICENSE file in the project root for more information.
*/
// Copyright (c) 2004, Open Cloud Limited.

package org.postgresql.benchmark.encoding;

import org.postgresql.core.Utils;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
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.Threads;
import org.openjdk.jmh.annotations.Warmup;
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.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.concurrent.TimeUnit;

/**
* Tests the performance of UTF-8 encoding. UTF-8 is used a lot, so we need to know the performance
*/
@Fork(value = 5, jvmArgsPrepend = "-Xmx128m")
@Measurement(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS)
@State(Scope.Thread)
@Threads(1)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class UTF8Encoding {

@Param({"1", "5", "10", "50", "100"})
public int length;

private String source;
private CharsetEncoder encoder;
private ByteBuffer buf;
private static final Charset UTF_8 = Charset.forName("UTF-8");

@Setup
public void setup() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append("Hello мир,");
}
source = sb.toString();
encoder = UTF_8.newEncoder();
buf = ByteBuffer.allocate(10240);
}

@Benchmark
public byte[] utilsEncodeUTF8_old() {
ByteBuffer buf = UTF_8.encode(CharBuffer.wrap(source));
byte[] b = new byte[buf.limit()];
buf.get(b, 0, buf.limit());
return b;
}

@Benchmark
public byte[] utilsEncodeUTF8_current() {
return Utils.encodeUTF8(source);
}

@Benchmark
public byte[] string_getBytes() {
return source.getBytes(UTF_8);
}

@Benchmark
public ByteBuffer charset_encode() {
return UTF_8.encode(source);
}

@Benchmark
public Object encoder_byteBufferReuse() throws CharacterCodingException {
buf.clear();
return encoder.encode(CharBuffer.wrap(source), buf, true);
}

public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(UTF8Encoding.class.getSimpleName())
//.addProfiler(GCProfiler.class)
.detectJvmArgs()
.build();

new Runner(opt).run();
}
}

0 comments on commit 409bd25

Please sign in to comment.