From 7989b57c6058a54dd0dd7fafe572cca9f4c1fd85 Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Mon, 4 Jan 2016 13:16:28 -0800 Subject: [PATCH 1/4] Added perf test for command construction --- .../perf/CommandConstructionPerfTest.java | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 hystrix-core/src/jmh/java/com/netflix/hystrix/perf/CommandConstructionPerfTest.java diff --git a/hystrix-core/src/jmh/java/com/netflix/hystrix/perf/CommandConstructionPerfTest.java b/hystrix-core/src/jmh/java/com/netflix/hystrix/perf/CommandConstructionPerfTest.java new file mode 100644 index 000000000..881591bcd --- /dev/null +++ b/hystrix-core/src/jmh/java/com/netflix/hystrix/perf/CommandConstructionPerfTest.java @@ -0,0 +1,130 @@ +/** + * Copyright 2014 Netflix, Inc. + *

+ * Licensed 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. + */ +package com.netflix.hystrix.perf; + +import com.netflix.hystrix.HystrixCommand; +import com.netflix.hystrix.HystrixCommandGroupKey; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; + +import java.util.concurrent.TimeUnit; + +public class CommandConstructionPerfTest { + + static HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey("Group"); + +// static HystrixCommandProperties.Setter threadIsolatedCommandDefaults = HystrixCommandProperties.Setter() +// .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD) +// .withRequestCacheEnabled(true) +// .withRequestLogEnabled(true) +// .withCircuitBreakerEnabled(true) +// .withCircuitBreakerForceOpen(false); +// +// static HystrixCommandProperties.Setter semaphoreIsolatedCommandDefaults = HystrixCommandProperties.Setter() +// .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE) +// .withRequestCacheEnabled(true) +// .withRequestLogEnabled(true) +// .withCircuitBreakerEnabled(true) +// .withCircuitBreakerForceOpen(false); +// +// static HystrixThreadPoolProperties.Setter threadPoolDefaults = HystrixThreadPoolProperties.Setter() +// .withCoreSize(100); +// +// private static HystrixCommandProperties.Setter getCommandSetter(HystrixCommandProperties.ExecutionIsolationStrategy isolationStrategy) { +// switch (isolationStrategy) { +// case THREAD: return threadIsolatedCommandDefaults; +// default: return semaphoreIsolatedCommandDefaults; +// } +// } + +// @State(Scope.Thread) +// public static class CommandState { +// HystrixCommand command; +// +// @Param({"THREAD", "SEMAPHORE"}) +// public HystrixCommandProperties.ExecutionIsolationStrategy isolationStrategy; +// +// @Param({"1", "100", "10000"}) +// public int blackholeConsumption; +// +// @Setup(Level.Invocation) +// public void setUp() { +// command = new HystrixCommand( +// HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("PERF")) +// .andCommandPropertiesDefaults(getCommandSetter(isolationStrategy)) +// .andThreadPoolPropertiesDefaults(threadPoolDefaults) +// ) { +// @Override +// protected Integer run() throws Exception { +// Blackhole.consumeCPU(blackholeConsumption); +// return 1; +// } +// +// @Override +// protected Integer getFallback() { +// return 2; +// } +// }; +// } +// } + +// @State(Scope.Benchmark) +// public static class ExecutorState { +// ExecutorService executorService; +// +// @Setup +// public void setUp() { +// executorService = Executors.newFixedThreadPool(100); +// } +// +// @TearDown +// public void tearDown() { +// List runnables = executorService.shutdownNow(); +// } +// } +// +// @State(Scope.Benchmark) +// public static class ThreadPoolState { +// HystrixThreadPool hystrixThreadPool; +// +// @Setup +// public void setUp() { +// hystrixThreadPool = new HystrixThreadPool.HystrixThreadPoolDefault( +// HystrixThreadPoolKey.Factory.asKey("PERF") +// , HystrixThreadPoolProperties.Setter().withCoreSize(100)); +// } +// +// @TearDown +// public void tearDown() { +// hystrixThreadPool.getExecutor().shutdownNow(); +// } +// } + + + @Benchmark + @BenchmarkMode({Mode.SampleTime}) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public HystrixCommand constructHystrixCommandByGroupKeyOnly() { + return new HystrixCommand(groupKey) { + @Override + protected Integer run() throws Exception { + return 1; + } + }; + } +} From 36d7c1d50046c8c3fdc7a4bb68ea0de2f7cdda0e Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Mon, 4 Jan 2016 13:40:56 -0800 Subject: [PATCH 2/4] Reduced gets on key name concurrent hash maps --- hystrix-core/build.gradle | 3 ++- .../java/com/netflix/hystrix/HystrixCommandGroupKey.java | 5 +++-- .../src/main/java/com/netflix/hystrix/HystrixCommandKey.java | 5 +++-- .../main/java/com/netflix/hystrix/HystrixThreadPoolKey.java | 5 +++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/hystrix-core/build.gradle b/hystrix-core/build.gradle index 9b79142fd..60aa32db9 100644 --- a/hystrix-core/build.gradle +++ b/hystrix-core/build.gradle @@ -37,10 +37,11 @@ jar { jmh { fork = 10 iterations = 3 - jmhVersion = '1.11.1' + jmhVersion = '1.11.2' profilers = ['gc'] threads = 8 warmup = '1s' warmupBatchSize = 1 warmupIterations = 5 + include = '.*Construction.*' } \ No newline at end of file diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandGroupKey.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandGroupKey.java index 1928cbb34..0a6a5fd3c 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandGroupKey.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandGroupKey.java @@ -50,9 +50,10 @@ private Factory() { public static HystrixCommandGroupKey asKey(String name) { HystrixCommandGroupKey k = intern.get(name); if (k == null) { - intern.putIfAbsent(name, new HystrixCommandGroupDefault(name)); + k = new HystrixCommandGroupDefault(name); + intern.putIfAbsent(name, k); } - return intern.get(name); + return k; } private static class HystrixCommandGroupDefault implements HystrixCommandGroupKey { diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandKey.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandKey.java index 49b9a368a..900ce44b3 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandKey.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixCommandKey.java @@ -48,9 +48,10 @@ private Factory() { public static HystrixCommandKey asKey(String name) { HystrixCommandKey k = intern.get(name); if (k == null) { - intern.putIfAbsent(name, new HystrixCommandKeyDefault(name)); + k = new HystrixCommandKeyDefault(name); + intern.putIfAbsent(name, k); } - return intern.get(name); + return k; } private static class HystrixCommandKeyDefault implements HystrixCommandKey { diff --git a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolKey.java b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolKey.java index 87619d83c..f6cf4d8d9 100644 --- a/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolKey.java +++ b/hystrix-core/src/main/java/com/netflix/hystrix/HystrixThreadPoolKey.java @@ -50,9 +50,10 @@ private Factory() { public static HystrixThreadPoolKey asKey(String name) { HystrixThreadPoolKey k = intern.get(name); if (k == null) { - intern.putIfAbsent(name, new HystrixThreadPoolKeyDefault(name)); + k = new HystrixThreadPoolKeyDefault(name); + intern.putIfAbsent(name, k); } - return intern.get(name); + return k; } private static class HystrixThreadPoolKeyDefault implements HystrixThreadPoolKey { From 3474dfa52deb26fbb62d8a38775a5f7ae0adc19e Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Mon, 4 Jan 2016 13:48:13 -0800 Subject: [PATCH 3/4] Remove include block in JMH config --- hystrix-core/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/hystrix-core/build.gradle b/hystrix-core/build.gradle index 60aa32db9..8598450b3 100644 --- a/hystrix-core/build.gradle +++ b/hystrix-core/build.gradle @@ -43,5 +43,4 @@ jmh { warmup = '1s' warmupBatchSize = 1 warmupIterations = 5 - include = '.*Construction.*' } \ No newline at end of file From 07cc698546faa6f927fe32d33ce92ca555fc2a5e Mon Sep 17 00:00:00 2001 From: Matt Jacobs Date: Mon, 4 Jan 2016 13:49:27 -0800 Subject: [PATCH 4/4] Cleanup commented-out code --- .../perf/CommandConstructionPerfTest.java | 88 ------------------- 1 file changed, 88 deletions(-) diff --git a/hystrix-core/src/jmh/java/com/netflix/hystrix/perf/CommandConstructionPerfTest.java b/hystrix-core/src/jmh/java/com/netflix/hystrix/perf/CommandConstructionPerfTest.java index 881591bcd..714ddc1e8 100644 --- a/hystrix-core/src/jmh/java/com/netflix/hystrix/perf/CommandConstructionPerfTest.java +++ b/hystrix-core/src/jmh/java/com/netflix/hystrix/perf/CommandConstructionPerfTest.java @@ -28,94 +28,6 @@ public class CommandConstructionPerfTest { static HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory.asKey("Group"); -// static HystrixCommandProperties.Setter threadIsolatedCommandDefaults = HystrixCommandProperties.Setter() -// .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD) -// .withRequestCacheEnabled(true) -// .withRequestLogEnabled(true) -// .withCircuitBreakerEnabled(true) -// .withCircuitBreakerForceOpen(false); -// -// static HystrixCommandProperties.Setter semaphoreIsolatedCommandDefaults = HystrixCommandProperties.Setter() -// .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE) -// .withRequestCacheEnabled(true) -// .withRequestLogEnabled(true) -// .withCircuitBreakerEnabled(true) -// .withCircuitBreakerForceOpen(false); -// -// static HystrixThreadPoolProperties.Setter threadPoolDefaults = HystrixThreadPoolProperties.Setter() -// .withCoreSize(100); -// -// private static HystrixCommandProperties.Setter getCommandSetter(HystrixCommandProperties.ExecutionIsolationStrategy isolationStrategy) { -// switch (isolationStrategy) { -// case THREAD: return threadIsolatedCommandDefaults; -// default: return semaphoreIsolatedCommandDefaults; -// } -// } - -// @State(Scope.Thread) -// public static class CommandState { -// HystrixCommand command; -// -// @Param({"THREAD", "SEMAPHORE"}) -// public HystrixCommandProperties.ExecutionIsolationStrategy isolationStrategy; -// -// @Param({"1", "100", "10000"}) -// public int blackholeConsumption; -// -// @Setup(Level.Invocation) -// public void setUp() { -// command = new HystrixCommand( -// HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("PERF")) -// .andCommandPropertiesDefaults(getCommandSetter(isolationStrategy)) -// .andThreadPoolPropertiesDefaults(threadPoolDefaults) -// ) { -// @Override -// protected Integer run() throws Exception { -// Blackhole.consumeCPU(blackholeConsumption); -// return 1; -// } -// -// @Override -// protected Integer getFallback() { -// return 2; -// } -// }; -// } -// } - -// @State(Scope.Benchmark) -// public static class ExecutorState { -// ExecutorService executorService; -// -// @Setup -// public void setUp() { -// executorService = Executors.newFixedThreadPool(100); -// } -// -// @TearDown -// public void tearDown() { -// List runnables = executorService.shutdownNow(); -// } -// } -// -// @State(Scope.Benchmark) -// public static class ThreadPoolState { -// HystrixThreadPool hystrixThreadPool; -// -// @Setup -// public void setUp() { -// hystrixThreadPool = new HystrixThreadPool.HystrixThreadPoolDefault( -// HystrixThreadPoolKey.Factory.asKey("PERF") -// , HystrixThreadPoolProperties.Setter().withCoreSize(100)); -// } -// -// @TearDown -// public void tearDown() { -// hystrixThreadPool.getExecutor().shutdownNow(); -// } -// } - - @Benchmark @BenchmarkMode({Mode.SampleTime}) @OutputTimeUnit(TimeUnit.MICROSECONDS)