Skip to content

add benchmark to retrieve products #390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
@@ -26,3 +26,5 @@ jobs:
CTP_CLIENT_SECRET: ${{ secrets.CTP_CLIENT_SECRET_PR }}
CTP_PROJECT_KEY: ${{ secrets.CTP_PROJECT_KEY_PR }}
CTP_JVM_SDK_LOG_LEVEL: OFF
- name: Output results
run: cat commercetools/commercetools-sdk-compat-v1/build/results/jmh/results.txt
8 changes: 5 additions & 3 deletions commercetools/commercetools-sdk-compat-v1/build.gradle
Original file line number Diff line number Diff line change
@@ -3,9 +3,10 @@ apply plugin: "me.champeau.jmh"
jmh {
iterations = 10
benchmarkMode = ['thrpt', 'avgt']
threads = 25
fork = 3
timeOnIteration = '1s'
threads = 10
fork = 1
timeOnIteration = '3s'
excludes = ['.*retrieveProject.*']
}
dependencies {

@@ -23,6 +24,7 @@ dependencies {

jmhImplementation project(':commercetools:commercetools-async-http-client')
jmhImplementation project(':commercetools:commercetools-apachehttp-client')
jmhImplementation ctsdkv1.http version ctsdkv1.version
testImplementation project(':commercetools:commercetools-http-client')
testImplementation ctsdkv1.client version ctsdkv1.version
testImplementation ctsdkv1.models version ctsdkv1.version
Original file line number Diff line number Diff line change
@@ -2,21 +2,34 @@
package com.commercetools.benchmark;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import com.commercetools.api.client.ApiInternalLoggerFactory;
import com.commercetools.api.client.ProjectApiRoot;
import com.commercetools.api.defaultconfig.ApiRootBuilder;
import com.commercetools.api.defaultconfig.ServiceRegion;
import com.commercetools.api.models.common.LocalizedString;
import com.commercetools.api.models.product.Product;
import com.commercetools.api.models.product.ProductProjectionPagedQueryResponse;
import com.commercetools.api.models.product_type.AttributeTypeBuilder;
import com.commercetools.api.models.product_type.ProductType;
import com.commercetools.api.models.tax_category.TaxCategory;
import com.commercetools.compat.CompatSphereClient;
import com.commercetools.http.apachehttp.CtApacheHttpClient;
import com.commercetools.http.asynchttp.CtAsyncHttpClient;
import com.commercetools.http.okhttp4.CtOkHttp4Client;

import io.sphere.sdk.client.BlockingSphereClient;
import io.sphere.sdk.client.SphereClient;
import io.sphere.sdk.client.SphereClientFactory;
import io.sphere.sdk.client.*;
import io.sphere.sdk.products.ProductProjection;
import io.sphere.sdk.products.queries.ProductProjectionQuery;
import io.sphere.sdk.projects.queries.ProjectGet;
import io.sphere.sdk.queries.PagedQueryResult;
import io.vrap.rmf.base.client.ApiHttpResponse;
import io.vrap.rmf.base.client.oauth2.ClientCredentials;

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

public class ClientBenchmark {
@@ -30,46 +43,158 @@ public static class ClientState {

private BlockingSphereClient sphereClient;

private BlockingSphereClient sphereApacheClient;

private BlockingSphereClient compatClient;

private BlockingSphereClient compatOkHttpClient;

private BlockingSphereClient compatApacheClient;

private List<Product> productsList;

private TaxCategory taxCategory;

private ProductType productType;

@Setup(Level.Trial)
public void init() {
ahcApiRoot = ApiRootBuilder.of(new CtAsyncHttpClient())
.defaultClient(
ClientCredentials.of().withClientId(getClientId()).withClientSecret(getClientSecret()).build(),
ServiceRegion.GCP_EUROPE_WEST1)
.withInternalLoggerFactory(ApiInternalLoggerFactory::get, org.slf4j.event.Level.DEBUG,
org.slf4j.event.Level.DEBUG)
.build(getProjectKey());

apacheApiRoot = ApiRootBuilder.of(new CtApacheHttpClient())
.defaultClient(
ClientCredentials.of().withClientId(getClientId()).withClientSecret(getClientSecret()).build(),
ServiceRegion.GCP_EUROPE_WEST1)
.withInternalLoggerFactory(ApiInternalLoggerFactory::get, org.slf4j.event.Level.DEBUG,
org.slf4j.event.Level.DEBUG)
.build(getProjectKey());

okhttpApiRoot = ApiRootBuilder.of(new CtOkHttp4Client())
.defaultClient(
ClientCredentials.of().withClientId(getClientId()).withClientSecret(getClientSecret()).build(),
ServiceRegion.GCP_EUROPE_WEST1)
.withInternalLoggerFactory(ApiInternalLoggerFactory::get, org.slf4j.event.Level.DEBUG,
org.slf4j.event.Level.DEBUG)
.build(getProjectKey());

final SphereClientFactory factory = SphereClientFactory.of();
final SphereClientFactory factory = SphereClientFactory.of(SphereAsyncHttpClientFactory::create);
final SphereClient client = factory.createClient(getProjectKey(), //replace with your project key
getClientId(), //replace with your client id
getClientSecret()); //replace with your client secret

sphereClient = BlockingSphereClient.of(client, Duration.ofSeconds(10));

final SphereClientFactory apacheFactory = SphereClientFactory.of(SphereApacheHttpClientFactory::create);
final SphereClient apacheClient = apacheFactory.createClient(getProjectKey(), //replace with your project key
getClientId(), //replace with your client id
getClientSecret()); //replace with your client secret

sphereApacheClient = BlockingSphereClient.of(apacheClient, Duration.ofSeconds(10));

compatClient = BlockingSphereClient.of(CompatSphereClient.of(ahcApiRoot), Duration.ofSeconds(10));

compatOkHttpClient = BlockingSphereClient.of(CompatSphereClient.of(okhttpApiRoot), Duration.ofSeconds(10));

compatApacheClient = BlockingSphereClient.of(CompatSphereClient.of(apacheApiRoot), Duration.ofSeconds(10));

productType = createProductType();

taxCategory = createTaxCategory();
productsList = createProducts(taxCategory, productType);
}

@TearDown(Level.Trial)
public void tearDown() {
deleteProducts(productsList);
deleteProductType(productType);
deleteTaxCategory(taxCategory);
ahcApiRoot.close();
compatClient.close();
compatOkHttpClient.close();
compatApacheClient.close();
apacheApiRoot.close();
sphereApacheClient.close();
okhttpApiRoot.close();
sphereClient.close();
}

public ProductType createProductType() {
String suffix = randomKey();
return ahcApiRoot.productTypes()
.create(builder -> builder.key("benchmark-" + suffix)
.name("benchmark")
.description("benchmark")
.plusAttributes(attributeBuilder -> attributeBuilder.type(AttributeTypeBuilder::textBuilder)
.isRequired(false)
.name("benchmark-color")
.isSearchable(true)
.label(LocalizedString.ofEnglish("color"))))
.executeBlocking()
.getBody();
}

private TaxCategory createTaxCategory() {
String suffix = randomKey();
return ahcApiRoot.taxCategories()
.create(builder -> builder.key("benchmark-" + suffix)
.name("benchmark-" + suffix)
.description("benchmark-" + suffix)
.plusRates(rateBuilder -> rateBuilder.name("Mwst")
.country("DE")
.amount(0.19)
.includedInPrice(true)))
.executeBlocking()
.getBody();
}

private List<Product> createProducts(TaxCategory taxCategory, ProductType productType) {
String productSuffix = randomKey();
List<Product> products = new ArrayList<>();
for (int i = 0; i < 150; i++) {
String suffix = productSuffix + "-" + i;
Product product = ahcApiRoot.products()
.create(
builder -> builder.key("benchmark-" + suffix)
.productType(p -> p.id(productType.getId()))
.taxCategory(t -> t.id(taxCategory.getId()))
.name(LocalizedString.ofEnglish("benchmark-" + suffix))
.slug(LocalizedString.ofEnglish("benchmark-" + suffix))
.description(LocalizedString.ofEnglish("benchmark-" + suffix))
.masterVariant(variantBuilder -> variantBuilder.key("benchmark-variant1-" + suffix)
.sku("benchmark-variant1-" + suffix)
.plusPrices(price -> price.country("DE")
.value(moneyBuilder -> moneyBuilder.centAmount(100L)
.currencyCode("EUR")))
.plusAttributes(
attribute -> attribute.name("benchmark-color").value("red" + suffix))))
.executeBlocking()
.getBody();
products.add(product);
}
return products;
}

private void deleteProducts(List<Product> products) {
products.forEach(product -> ahcApiRoot.products().delete(product).executeBlocking());
}

private void deleteProductType(ProductType productType) {
ahcApiRoot.productTypes().delete(productType).executeBlocking();
}

private void deleteTaxCategory(TaxCategory taxCategory) {
ahcApiRoot.taxCategories().delete(taxCategory).executeBlocking();
}

public static String randomKey() {
return "random-key-" + UUID.randomUUID().toString();
}
}

@Benchmark
@@ -92,11 +217,89 @@ public void retrieveProjectV1_AHC(ClientState state) {
state.sphereClient.executeBlocking(ProjectGet.of());
}

@Benchmark
public void retrieveProjectV1_Apache(ClientState state) {
state.sphereApacheClient.executeBlocking(ProjectGet.of());
}

@Benchmark
public void retrieveProjectV2_Compat(ClientState state) {
state.compatClient.executeBlocking(ProjectGet.of());
}

@Benchmark
public void retrieveProjectV2_CompatOkHttp(ClientState state) {
state.compatOkHttpClient.executeBlocking(ProjectGet.of());
}

@Benchmark
public void retrieveProductsV1_AHC(ClientState state) {
final PagedQueryResult<ProductProjection> response = state.sphereClient
.executeBlocking(ProductProjectionQuery.ofStaged().withLimit(100));
Assertions.assertThat(response.getCount()).isEqualTo(100);
}

@Benchmark
public void retrieveProductsV2_CompatAHC(ClientState state) {
final PagedQueryResult<ProductProjection> response = state.compatClient
.executeBlocking(ProductProjectionQuery.ofStaged().withLimit(100));
Assertions.assertThat(response.getCount()).isEqualTo(100);
}

@Benchmark
public void retrieveProductsV2_AHC(ClientState state) {
final ApiHttpResponse<ProductProjectionPagedQueryResponse> response = state.ahcApiRoot.productProjections()
.get()
.withStaged(true)
.withLimit(100)
.executeBlocking();
Assertions.assertThat(response.getBody().getCount()).isEqualTo(100);

}

@Benchmark
public void retrieveProductsV1_Apache(ClientState state) {
final PagedQueryResult<ProductProjection> response = state.sphereApacheClient
.executeBlocking(ProductProjectionQuery.ofStaged().withLimit(100));
Assertions.assertThat(response.getCount()).isEqualTo(100);
}

@Benchmark
public void retrieveProductsV2_CompatApache(ClientState state) {
final PagedQueryResult<ProductProjection> response = state.compatApacheClient
.executeBlocking(ProductProjectionQuery.ofStaged().withLimit(100));
Assertions.assertThat(response.getCount()).isEqualTo(100);
}

@Benchmark
public void retrieveProductsV2_Apache(ClientState state) {
final ApiHttpResponse<ProductProjectionPagedQueryResponse> response = state.apacheApiRoot.productProjections()
.get()
.withStaged(true)
.withLimit(100)
.executeBlocking();

Assertions.assertThat(response.getBody().getCount()).isEqualTo(100);
}

@Benchmark
public void retrieveProductsV2_CompatOkHttp(ClientState state) {
final PagedQueryResult<ProductProjection> response = state.compatOkHttpClient
.executeBlocking(ProductProjectionQuery.ofStaged().withLimit(100));
Assertions.assertThat(response.getCount()).isEqualTo(100);
}

@Benchmark
public void retrieveProductsV2_OkHtp(ClientState state) {
final ApiHttpResponse<ProductProjectionPagedQueryResponse> response = state.okhttpApiRoot.productProjections()
.get()
.withStaged(true)
.withLimit(100)
.executeBlocking();

Assertions.assertThat(response.getBody().getCount()).isEqualTo(100);
}

public static String getProjectKey() {
return System.getenv("CTP_PROJECT_KEY");
}
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@

<logger name="commercetools" level="ERROR"/>

<root level="INFO">
<root level="ERROR">
<appender-ref ref="STDOUT" />
</root>
</configuration>
1 change: 1 addition & 0 deletions gradle-scripts/extensions.gradle
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ ext {
client: 'com.commercetools.sdk.jvm.core:commercetools-java-client-core:2.9.0',
models: 'com.commercetools.sdk.jvm.core:commercetools-models:2.9.0',
convenience: 'com.commercetools.sdk.jvm.core:commercetools-convenience:2.9.0',
http: 'com.commercetools.sdk.jvm.core:commercetools-java-client-ahc-2_12:2.9.0',
version: {
strictly '[1.62.0,)'
prefer '2.9.0'