Skip to content

Commit

Permalink
add benchmark for okhttp unzip
Browse files Browse the repository at this point in the history
  • Loading branch information
jenschude committed Oct 10, 2024
1 parent 14cbeb5 commit 13a06ee
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 6 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ plugins {
id 'io.github.gradle-nexus.publish-plugin' version '1.3.0'
id 'com.github.jk1.dependency-license-report' version '2.0'

id "me.champeau.jmh" version "0.7.2"
id "me.champeau.jmh" version "0.6.8"
id "jacoco"
}

Expand Down
12 changes: 11 additions & 1 deletion commercetools/commercetools-okhttp-client3/build.gradle
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
apply plugin: "me.champeau.jmh"

jmh {
iterations = 5
benchmarkMode = ['thrpt']
threads = 25
fork = 3
timeOnIteration = '1s'
profilers = ['gc']
}

dependencies {
api project(":rmf:rmf-java-base")

api "com.squareup.okio:okio:3.9.0"
implementation "com.squareup.okio:okio:3.9.0"
api "com.squareup.okhttp3:okhttp:3.14.9" version {
strictly "[3.0,4.0["
prefer "3.14.9"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@

package com.commercetools.http.okhttp3;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPOutputStream;

import io.vrap.rmf.base.client.ApiHttpResponse;

import org.assertj.core.api.Assertions;
import org.openjdk.jmh.annotations.*;

import okhttp3.*;
import okio.Okio;

public class UnzipBenchmark {

@State(Scope.Benchmark)
public static class InterceptorState {
private CtOkHttp3Client.UnzippingInterceptor interceptor;

@Setup(Level.Trial)
public void init() {
interceptor = new CtOkHttp3Client.UnzippingInterceptor();
printUsedMemory();

}

@TearDown(Level.Trial)
public void tearDown() {
printUsedMemory();
}
}
@Benchmark
public void unzip(InterceptorState state) throws IOException {

ByteArrayOutputStream os = new ByteArrayOutputStream();
GZIPOutputStream gzipOs = new GZIPOutputStream(os);
byte[] buffer = "Sample Text".getBytes();
gzipOs.write(buffer, 0, buffer.length);
gzipOs.close();
ByteArrayInputStream inputStream = new ByteArrayInputStream(os.toByteArray());

Response gzipped = new Response.Builder().request(new Request.Builder().url("http://localhost").build())
.protocol(Protocol.HTTP_1_1)
.addHeader("content-encoding", "gzip")
.addHeader("content-type", "application/json")
.code(200)
.message("Ok")
.body(ResponseBody.create(MediaType.parse("application/json"), -1L,
Okio.buffer(Okio.source(inputStream))))
.build();
Assertions.assertThat(gzipped.body().source().isOpen()).isTrue();

Response unzipped = state.interceptor.unzip(gzipped);

Assertions.assertThat(gzipped.body().source().isOpen()).isTrue();
Assertions.assertThat(unzipped.body().source().isOpen()).isTrue();
Assertions.assertThat(inputStream.available()).isEqualTo(31);

ApiHttpResponse<byte[]> response = CtOkHttp3Client.toResponse(unzipped);

Assertions.assertThat(gzipped.body().source().isOpen()).isFalse();
Assertions.assertThat(unzipped.body().source().isOpen()).isFalse();
Assertions.assertThat(inputStream.available()).isEqualTo(0);

String text = new String(response.getBody(), StandardCharsets.UTF_8);
Assertions.assertThat(text).isEqualTo("Sample Text");
}

public static void printUsedMemory() {
long _usedMem;
long _total;
long _total2;
long _count = -1;
System.out.flush();
// loop to get a stable reading, since memory may be resized between the method calls
do {
_count++;
_total = Runtime.getRuntime().totalMemory();
try {
Thread.sleep(12);
}
catch (Exception ignore) {
}
long _free = Runtime.getRuntime().freeMemory();
_total2 = Runtime.getRuntime().totalMemory();
_usedMem = _total - _free;
} while (_total != _total2);
System.out.println("before GC: used=" + _usedMem + ", loopCount=" + _count + ", total=" + _total);
try {
Runtime.getRuntime().gc();
Thread.sleep(55);
Runtime.getRuntime().gc();
Thread.sleep(55);
Runtime.getRuntime().gc();
Thread.sleep(55);
Runtime.getRuntime().gc();
Thread.sleep(55);
}
catch (Exception ignore) {
}
// loop to get a stable reading, since memory may be resized between the method calls
do {
_count++;
_total = Runtime.getRuntime().totalMemory();
try {
Thread.sleep(12);
}
catch (Exception ignore) {
}
long _free = Runtime.getRuntime().freeMemory();
_total2 = Runtime.getRuntime().totalMemory();
_usedMem = _total - _free;
} while (_total != _total2);
System.out.println("after GC: used=" + _usedMem + ", loopCount=" + _count + ", total=" + _total);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ static ApiHttpResponse<byte[]> toResponse(final okhttp3.Response response) {
.map(Utils.wrapToCompletionException(okhttp3.ResponseBody::bytes))
.orElse(null),
response.message());
if (apiHttpResponse.getBody() != null) {
if (response.body() != null) {
response.body().close();
}
return apiHttpResponse;
Expand Down
10 changes: 10 additions & 0 deletions commercetools/commercetools-okhttp-client4/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
apply plugin: "me.champeau.jmh"

jmh {
iterations = 5
benchmarkMode = ['thrpt']
threads = 25
fork = 3
timeOnIteration = '1s'
profilers = ['gc']
}

dependencies {
api project(":rmf:rmf-java-base")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@

package com.commercetools.http.okhttp4;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPOutputStream;

import io.vrap.rmf.base.client.ApiHttpResponse;

import org.assertj.core.api.Assertions;
import org.openjdk.jmh.annotations.*;

import okhttp3.*;
import okio.Okio;

public class UnzipBenchmark {

@State(Scope.Benchmark)
public static class InterceptorState {
private CtOkHttp4Client.UnzippingInterceptor interceptor;

@Setup(Level.Trial)
public void init() {
interceptor = new CtOkHttp4Client.UnzippingInterceptor();
printUsedMemory();

}

@TearDown(Level.Trial)
public void tearDown() {
printUsedMemory();
}
}
@Benchmark
public void unzip(InterceptorState state) throws IOException {

ByteArrayOutputStream os = new ByteArrayOutputStream();
GZIPOutputStream gzipOs = new GZIPOutputStream(os);
byte[] buffer = "Sample Text".getBytes();
gzipOs.write(buffer, 0, buffer.length);
gzipOs.close();
ByteArrayInputStream inputStream = new ByteArrayInputStream(os.toByteArray());

Response gzipped = new Response.Builder().request(new Request.Builder().url("http://localhost").build())
.protocol(Protocol.HTTP_1_1)
.addHeader("content-encoding", "gzip")
.addHeader("content-type", "application/json")
.code(200)
.message("Ok")
.body(ResponseBody.create(MediaType.parse("application/json"), -1L,
Okio.buffer(Okio.source(inputStream))))
.build();
Assertions.assertThat(gzipped.body().source().isOpen()).isTrue();

Response unzipped = state.interceptor.unzip(gzipped);

Assertions.assertThat(gzipped.body().source().isOpen()).isTrue();
Assertions.assertThat(unzipped.body().source().isOpen()).isTrue();
Assertions.assertThat(inputStream.available()).isEqualTo(31);

ApiHttpResponse<byte[]> response = CtOkHttp4Client.toResponse(unzipped);

Assertions.assertThat(gzipped.body().source().isOpen()).isFalse();
Assertions.assertThat(unzipped.body().source().isOpen()).isFalse();
Assertions.assertThat(inputStream.available()).isEqualTo(0);

String text = new String(response.getBody(), StandardCharsets.UTF_8);
Assertions.assertThat(text).isEqualTo("Sample Text");
}

public static void printUsedMemory() {
long _usedMem;
long _total;
long _total2;
long _count = -1;
System.out.flush();
// loop to get a stable reading, since memory may be resized between the method calls
do {
_count++;
_total = Runtime.getRuntime().totalMemory();
try {
Thread.sleep(12);
}
catch (Exception ignore) {
}
long _free = Runtime.getRuntime().freeMemory();
_total2 = Runtime.getRuntime().totalMemory();
_usedMem = _total - _free;
} while (_total != _total2);
System.out.println("before GC: used=" + _usedMem + ", loopCount=" + _count + ", total=" + _total);
try {
Runtime.getRuntime().gc();
Thread.sleep(55);
Runtime.getRuntime().gc();
Thread.sleep(55);
Runtime.getRuntime().gc();
Thread.sleep(55);
Runtime.getRuntime().gc();
Thread.sleep(55);
}
catch (Exception ignore) {
}
// loop to get a stable reading, since memory may be resized between the method calls
do {
_count++;
_total = Runtime.getRuntime().totalMemory();
try {
Thread.sleep(12);
}
catch (Exception ignore) {
}
long _free = Runtime.getRuntime().freeMemory();
_total2 = Runtime.getRuntime().totalMemory();
_usedMem = _total - _free;
} while (_total != _total2);
System.out.println("after GC: used=" + _usedMem + ", loopCount=" + _count + ", total=" + _total);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public CompletableFuture<ApiHttpResponse<byte[]>> execute(final ApiHttpRequest r

}

private static ApiHttpResponse<byte[]> toResponse(final okhttp3.Response response) {
static ApiHttpResponse<byte[]> toResponse(final okhttp3.Response response) {
final ApiHttpHeaders apiHttpHeaders = new ApiHttpHeaders(response.headers()
.toMultimap()
.entrySet()
Expand All @@ -120,7 +120,7 @@ private static ApiHttpResponse<byte[]> toResponse(final okhttp3.Response respons
.map(Utils.wrapToCompletionException(okhttp3.ResponseBody::bytes))
.orElse(null),
response.message());
if (apiHttpResponse.getBody() != null) {
if (response.body() != null) {
response.close();
}
return apiHttpResponse;
Expand Down Expand Up @@ -201,7 +201,7 @@ public okhttp3.Response intercept(Chain chain) throws IOException {
return unzip(response);
}

private okhttp3.Response unzip(final okhttp3.Response response) {
okhttp3.Response unzip(final okhttp3.Response response) {
if (!"gzip".equalsIgnoreCase(response.header("Content-Encoding"))) {
return response;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,63 @@

package com.commercetools.http.okhttp4;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPOutputStream;

import io.vrap.rmf.base.client.ApiHttpResponse;
import io.vrap.rmf.base.client.HttpClientSupplier;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

import okhttp3.*;
import okio.Okio;

public class SupplierTest {
@Test
public void testCreate() {
Assertions.assertThat(HttpClientSupplier.of().get()).isInstanceOf(CtOkHttp4Client.class);
}

@Test
public void testUnzip() throws IOException {

ByteArrayOutputStream os = new ByteArrayOutputStream();
GZIPOutputStream gzipOs = new GZIPOutputStream(os);
byte[] buffer = "Sample Text".getBytes();
gzipOs.write(buffer, 0, buffer.length);
gzipOs.close();
ByteArrayInputStream inputStream = new ByteArrayInputStream(os.toByteArray());

CtOkHttp4Client.UnzippingInterceptor interceptor = new CtOkHttp4Client.UnzippingInterceptor();

Response gzipped = new Response.Builder().request(new Request.Builder().url("http://localhost").build())
.protocol(Protocol.HTTP_1_1)
.addHeader("content-encoding", "gzip")
.addHeader("content-type", "application/json")
.code(200)
.message("Ok")
.body(ResponseBody.create(MediaType.parse("application/json"), -1L,
Okio.buffer(Okio.source(inputStream))))
.build();
Assertions.assertThat(gzipped.body().source().isOpen()).isTrue();

Response unzipped = interceptor.unzip(gzipped);

Assertions.assertThat(gzipped.body().source().isOpen()).isTrue();
Assertions.assertThat(unzipped.body().source().isOpen()).isTrue();
Assertions.assertThat(inputStream.available()).isEqualTo(31);

ApiHttpResponse<byte[]> response = CtOkHttp4Client.toResponse(unzipped);

Assertions.assertThat(gzipped.body().source().isOpen()).isFalse();
Assertions.assertThat(unzipped.body().source().isOpen()).isFalse();
Assertions.assertThat(inputStream.available()).isEqualTo(0);

String text = new String(response.getBody(), StandardCharsets.UTF_8);
Assertions.assertThat(text).isEqualTo("Sample Text");
}
}

0 comments on commit 13a06ee

Please sign in to comment.