Adrian Cole
10 years ago
6 changed files with 220 additions and 110 deletions
@ -1,46 +0,0 @@
@@ -1,46 +0,0 @@
|
||||
package feign.benchmark; |
||||
|
||||
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.Scope; |
||||
import org.openjdk.jmh.annotations.Setup; |
||||
import org.openjdk.jmh.annotations.State; |
||||
import org.openjdk.jmh.annotations.Warmup; |
||||
|
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
import feign.Contract; |
||||
import feign.jaxrs.JAXRSContract; |
||||
|
||||
@Measurement(iterations = 5, time = 1) |
||||
@Warmup(iterations = 5, time = 1) |
||||
@Fork(3) |
||||
@BenchmarkMode(Mode.Throughput) |
||||
@OutputTimeUnit(TimeUnit.SECONDS) |
||||
@State(Scope.Thread) |
||||
public class ContractBenchmarks { |
||||
|
||||
private Contract feignContract; |
||||
private Contract jaxrsContract; |
||||
|
||||
@Setup |
||||
public void setup() { |
||||
feignContract = new Contract.Default(); |
||||
jaxrsContract = new JAXRSContract(); |
||||
} |
||||
|
||||
@Benchmark |
||||
public void parseFeign() { |
||||
feignContract.parseAndValidatateMetadata(FeignTestInterface.class); |
||||
} |
||||
|
||||
@Benchmark |
||||
public void parseJAXRS() { |
||||
jaxrsContract.parseAndValidatateMetadata(JAXRSTestInterface.class); |
||||
} |
||||
|
||||
} |
@ -1,57 +0,0 @@
@@ -1,57 +0,0 @@
|
||||
package feign.benchmark; |
||||
|
||||
import java.lang.annotation.ElementType; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
import java.lang.annotation.Target; |
||||
import java.util.List; |
||||
|
||||
import javax.ws.rs.Consumes; |
||||
import javax.ws.rs.FormParam; |
||||
import javax.ws.rs.GET; |
||||
import javax.ws.rs.HeaderParam; |
||||
import javax.ws.rs.HttpMethod; |
||||
import javax.ws.rs.POST; |
||||
import javax.ws.rs.PUT; |
||||
import javax.ws.rs.Path; |
||||
import javax.ws.rs.PathParam; |
||||
import javax.ws.rs.Produces; |
||||
import javax.ws.rs.QueryParam; |
||||
|
||||
import feign.Headers; |
||||
import feign.Response; |
||||
|
||||
@Consumes("application/json") |
||||
interface JAXRSTestInterface { |
||||
|
||||
@GET |
||||
@Path("/?Action=GetUser&Version=2010-05-08&limit=1") |
||||
Response query(); |
||||
|
||||
@GET |
||||
@Path("/domains/{domainId}/records") |
||||
Response mixedParams(@PathParam("domainId") int id, @QueryParam("name") String nameFilter, |
||||
@QueryParam("type") String typeFilter); |
||||
|
||||
@PATCH |
||||
Response customMethod(); |
||||
|
||||
@Target({ElementType.METHOD}) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@HttpMethod("PATCH") |
||||
@interface PATCH { |
||||
|
||||
} |
||||
|
||||
@PUT |
||||
@Produces("application/json") |
||||
void bodyParam(List<String> body); |
||||
|
||||
@POST |
||||
void form(@FormParam("customer_name") String customer, @FormParam("user_name") String user, |
||||
@FormParam("password") String password); |
||||
|
||||
@POST |
||||
@Headers("Happy: sad") |
||||
void headers(@HeaderParam("Auth-Token") String token); |
||||
} |
@ -0,0 +1,85 @@
@@ -0,0 +1,85 @@
|
||||
package feign.benchmark; |
||||
|
||||
import com.squareup.okhttp.OkHttpClient; |
||||
import com.squareup.okhttp.Request; |
||||
|
||||
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.Scope; |
||||
import org.openjdk.jmh.annotations.Setup; |
||||
import org.openjdk.jmh.annotations.State; |
||||
import org.openjdk.jmh.annotations.TearDown; |
||||
import org.openjdk.jmh.annotations.Warmup; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
import feign.Feign; |
||||
import feign.Response; |
||||
import io.netty.buffer.ByteBuf; |
||||
import io.reactivex.netty.RxNetty; |
||||
import io.reactivex.netty.protocol.http.server.HttpServer; |
||||
import io.reactivex.netty.protocol.http.server.HttpServerRequest; |
||||
import io.reactivex.netty.protocol.http.server.HttpServerResponse; |
||||
import io.reactivex.netty.protocol.http.server.RequestHandler; |
||||
|
||||
@Measurement(iterations = 5, time = 1) |
||||
@Warmup(iterations = 10, time = 1) |
||||
@Fork(3) |
||||
@BenchmarkMode(Mode.Throughput) |
||||
@OutputTimeUnit(TimeUnit.SECONDS) |
||||
@State(Scope.Benchmark) |
||||
public class RealRequestBenchmarks { |
||||
|
||||
private static final int SERVER_PORT = 8765; |
||||
private HttpServer<ByteBuf, ByteBuf> server; |
||||
private OkHttpClient client; |
||||
private FeignTestInterface okFeign; |
||||
private Request queryRequest; |
||||
|
||||
@Setup |
||||
public void setup() { |
||||
server = RxNetty.createHttpServer(SERVER_PORT, new RequestHandler<ByteBuf, ByteBuf>() { |
||||
public rx.Observable handle(HttpServerRequest<ByteBuf> request, |
||||
HttpServerResponse<ByteBuf> response) { |
||||
return response.flush(); |
||||
} |
||||
}); |
||||
server.start(); |
||||
client = new OkHttpClient(); |
||||
client.setRetryOnConnectionFailure(false); |
||||
okFeign = Feign.builder() |
||||
.client(new feign.okhttp.OkHttpClient(client)) |
||||
.target(FeignTestInterface.class, "http://localhost:" + SERVER_PORT); |
||||
queryRequest = new Request.Builder() |
||||
.url("http://localhost:" + SERVER_PORT + "/?Action=GetUser&Version=2010-05-08&limit=1") |
||||
.build(); |
||||
} |
||||
|
||||
@TearDown |
||||
public void tearDown() throws InterruptedException { |
||||
server.shutdown(); |
||||
} |
||||
|
||||
/** |
||||
* How fast can we execute get commands synchronously? |
||||
*/ |
||||
@Benchmark |
||||
public com.squareup.okhttp.Response query_baseCaseUsingOkHttp() throws IOException { |
||||
com.squareup.okhttp.Response result = client.newCall(queryRequest).execute(); |
||||
result.body().close(); |
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* How fast can we execute get commands synchronously using Feign? |
||||
*/ |
||||
@Benchmark |
||||
public Response query_feignUsingOkHttp() { |
||||
return okFeign.query(); |
||||
} |
||||
} |
@ -0,0 +1,109 @@
@@ -0,0 +1,109 @@
|
||||
package feign.benchmark; |
||||
|
||||
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.Scope; |
||||
import org.openjdk.jmh.annotations.Setup; |
||||
import org.openjdk.jmh.annotations.State; |
||||
import org.openjdk.jmh.annotations.Warmup; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.Collection; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
import feign.Client; |
||||
import feign.Contract; |
||||
import feign.Feign; |
||||
import feign.MethodMetadata; |
||||
import feign.Request; |
||||
import feign.Response; |
||||
import feign.Target.HardCodedTarget; |
||||
|
||||
@Measurement(iterations = 5, time = 1) |
||||
@Warmup(iterations = 10, time = 1) |
||||
@Fork(3) |
||||
@BenchmarkMode(Mode.Throughput) |
||||
@OutputTimeUnit(TimeUnit.SECONDS) |
||||
@State(Scope.Thread) |
||||
public class WhatShouldWeCacheBenchmarks { |
||||
|
||||
private Contract feignContract; |
||||
private Contract cachedContact; |
||||
private Client fakeClient; |
||||
private Feign cachedFakeFeign; |
||||
private FeignTestInterface cachedFakeApi; |
||||
|
||||
@Setup |
||||
public void setup() { |
||||
feignContract = new Contract.Default(); |
||||
cachedContact = new Contract() { |
||||
private final List<MethodMetadata> cached = |
||||
new Default().parseAndValidatateMetadata(FeignTestInterface.class); |
||||
|
||||
public List<MethodMetadata> parseAndValidatateMetadata(Class<?> declaring) { |
||||
return cached; |
||||
} |
||||
}; |
||||
fakeClient = new Client() { |
||||
public Response execute(Request request, Request.Options options) throws IOException { |
||||
Map<String, Collection<String>> headers = new LinkedHashMap<String, Collection<String>>(); |
||||
return Response.create(200, "ok", headers, (byte[]) null); |
||||
} |
||||
}; |
||||
cachedFakeFeign = Feign.builder().client(fakeClient).build(); |
||||
cachedFakeApi = cachedFakeFeign.newInstance( |
||||
new HardCodedTarget<FeignTestInterface>(FeignTestInterface.class, "http://localhost")); |
||||
} |
||||
|
||||
/** |
||||
* How fast is parsing an api interface? |
||||
*/ |
||||
@Benchmark |
||||
public List<MethodMetadata> parseFeignContract() { |
||||
return feignContract.parseAndValidatateMetadata(FeignTestInterface.class); |
||||
} |
||||
|
||||
/** |
||||
* How fast is creating a feign instance for each http request, without considering network? |
||||
*/ |
||||
@Benchmark |
||||
public Response buildAndQuery_fake() { |
||||
return Feign.builder().client(fakeClient) |
||||
.target(FeignTestInterface.class, "http://localhost").query(); |
||||
} |
||||
|
||||
/** |
||||
* How fast is creating a feign instance for each http request, without considering network, and |
||||
* without re-parsing the annotated http api? |
||||
*/ |
||||
@Benchmark |
||||
public Response buildAndQuery_fake_cachedContract() { |
||||
return Feign.builder().contract(cachedContact).client(fakeClient) |
||||
.target(FeignTestInterface.class, "http://localhost").query(); |
||||
} |
||||
|
||||
/** |
||||
* How fast re-parsing the annotated http api for each http request, without considering network? |
||||
*/ |
||||
@Benchmark |
||||
public Response buildAndQuery_fake_cachedFeign() { |
||||
return cachedFakeFeign.newInstance( |
||||
new HardCodedTarget<FeignTestInterface>(FeignTestInterface.class, "http://localhost")) |
||||
.query(); |
||||
} |
||||
|
||||
/** |
||||
* How fast is our advice to use a cached api for each http request, without considering network? |
||||
*/ |
||||
@Benchmark |
||||
public Response buildAndQuery_fake_cachedApi() { |
||||
return cachedFakeApi.query(); |
||||
} |
||||
} |
Loading…
Reference in new issue