From 152167e803a616ff5a330f83a80bb142a42373bf Mon Sep 17 00:00:00 2001 From: akarnokd Date: Mon, 2 Feb 2015 23:40:03 +0100 Subject: [PATCH 1/2] Added perf tests for various container-like subscriptions --- .../rx/internal/util/SubscriptionList.java | 15 +- .../CompositeSubscriptionConcurrentPerf.java | 198 ++++++++++++++++++ .../CompositeSubscriptionPerf.java | 121 +++++++++++ .../MultipleAssignmentSubscriptionPerf.java | 91 ++++++++ .../subscriptions/SerialSubscriptionPerf.java | 91 ++++++++ .../SubscriptionListConcurrentPerf.java | 131 ++++++++++++ .../subscriptions/SubscriptionListPerf.java | 94 +++++++++ 7 files changed, 739 insertions(+), 2 deletions(-) create mode 100644 src/perf/java/rx/subscriptions/CompositeSubscriptionConcurrentPerf.java create mode 100644 src/perf/java/rx/subscriptions/CompositeSubscriptionPerf.java create mode 100644 src/perf/java/rx/subscriptions/MultipleAssignmentSubscriptionPerf.java create mode 100644 src/perf/java/rx/subscriptions/SerialSubscriptionPerf.java create mode 100644 src/perf/java/rx/subscriptions/SubscriptionListConcurrentPerf.java create mode 100644 src/perf/java/rx/subscriptions/SubscriptionListPerf.java diff --git a/src/main/java/rx/internal/util/SubscriptionList.java b/src/main/java/rx/internal/util/SubscriptionList.java index bb2e7f514d..23bddebee1 100644 --- a/src/main/java/rx/internal/util/SubscriptionList.java +++ b/src/main/java/rx/internal/util/SubscriptionList.java @@ -78,15 +78,17 @@ public void add(final Subscription s) { */ @Override public void unsubscribe() { + List list; synchronized (this) { if (unsubscribed) { return; } unsubscribed = true; + list = subscriptions; + subscriptions = null; } // we will only get here once - unsubscribeFromAll(subscriptions); - subscriptions = null; + unsubscribeFromAll(list); } private static void unsubscribeFromAll(Collection subscriptions) { @@ -119,4 +121,13 @@ private static void unsubscribeFromAll(Collection subscriptions) { } } } + /* perf support */ + public void clear() { + List list; + synchronized (this) { + list = subscriptions; + subscriptions = null; + } + unsubscribeFromAll(list); + } } diff --git a/src/perf/java/rx/subscriptions/CompositeSubscriptionConcurrentPerf.java b/src/perf/java/rx/subscriptions/CompositeSubscriptionConcurrentPerf.java new file mode 100644 index 0000000000..0c2eee5796 --- /dev/null +++ b/src/perf/java/rx/subscriptions/CompositeSubscriptionConcurrentPerf.java @@ -0,0 +1,198 @@ +/** + * 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 rx.subscriptions; + +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Group; +import org.openjdk.jmh.annotations.GroupThreads; +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 rx.Subscription; + +/** + * Benchmark typical composite subscription concurrent behavior. + *

+ * gradlew benchmarks "-Pjmh=-f 1 -tu s -bm thrpt -wi 5 -i 5 -r 1 .*CompositeSubscriptionConcurrentPerf.*" + *

+ * gradlew benchmarks "-Pjmh=-f 1 -tu ns -bm avgt -wi 5 -i 5 -r 1 .*CompositeSubscriptionConcurrentPerf.*" + */ +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.SECONDS) +@Threads(2) +@State(Scope.Group) +public class CompositeSubscriptionConcurrentPerf { + @Param({ "1", "1000", "100000" }) + public int loop; + + public final CompositeSubscription csub = new CompositeSubscription(); + @Param({ "1", "5", "10", "20" }) + public int count; + + public Subscription[] values; + @Setup + public void setup() { + values = new Subscription[count * 2]; + for (int i = 0; i < count * 2; i++) { + values[i] = new Subscription() { + @Override + public boolean isUnsubscribed() { + return false; + } + @Override + public void unsubscribe() { + + } + }; + } + } + + @Group("g1") + @GroupThreads(1) + @Benchmark + public void addRemoveT1() { + CompositeSubscription csub = this.csub; + Subscription[] values = this.values; + + for (int i = loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.add(values[j]); + } + for (int j = values.length - 1; j >= 0; j--) { + csub.remove(values[j]); + } + } + } + @Group("g1") + @GroupThreads(1) + @Benchmark + public void addRemoveT2() { + CompositeSubscription csub = this.csub; + Subscription[] values = this.values; + + for (int i = loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.add(values[j]); + } + for (int j = values.length - 1; j >= 0; j--) { + csub.remove(values[j]); + } + } + } + @Group("g2") + @GroupThreads(1) + @Benchmark + public void addRemoveHalfT1() { + CompositeSubscription csub = this.csub; + Subscription[] values = this.values; + int n = values.length; + + for (int i = loop; i > 0; i--) { + for (int j = n / 2 - 1; j >= 0; j--) { + csub.add(values[j]); + } + for (int j = n / 2 - 1; j >= 0; j--) { + csub.remove(values[j]); + } + } + } + @Group("g2") + @GroupThreads(1) + @Benchmark + public void addRemoveHalfT2() { + CompositeSubscription csub = this.csub; + Subscription[] values = this.values; + int n = values.length; + + for (int i = loop; i > 0; i--) { + for (int j = n - 1; j >= n / 2; j--) { + csub.add(values[j]); + } + for (int j = n - 1; j >= n / 2; j--) { + csub.remove(values[j]); + } + } + } + @Group("g3") + @GroupThreads(1) + @Benchmark + public void addClearT1() { + CompositeSubscription csub = this.csub; + Subscription[] values = this.values; + + for (int i = loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.add(values[j]); + } + csub.clear(); + } + } + @Group("g3") + @GroupThreads(1) + @Benchmark + public void addClearT2() { + CompositeSubscription csub = this.csub; + Subscription[] values = this.values; + + for (int i = loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.add(values[j]); + } + for (int j = values.length - 1; j >= 0; j--) { + csub.remove(values[j]); + } + } + } + @Group("g4") + @GroupThreads(1) + @Benchmark + public void addClearHalfT1() { + CompositeSubscription csub = this.csub; + Subscription[] values = this.values; + int n = values.length; + + for (int i = loop; i > 0; i--) { + for (int j = n / 2 - 1; j >= 0; j--) { + csub.add(values[j]); + } + csub.clear(); + } + } + @Group("g4") + @GroupThreads(1) + @Benchmark + public void addClearHalfT2() { + CompositeSubscription csub = this.csub; + Subscription[] values = this.values; + int n = values.length; + + for (int i = loop; i > 0; i--) { + for (int j = n - 1; j >= n / 2; j--) { + csub.add(values[j]); + } + csub.clear(); + } + } +} diff --git a/src/perf/java/rx/subscriptions/CompositeSubscriptionPerf.java b/src/perf/java/rx/subscriptions/CompositeSubscriptionPerf.java new file mode 100644 index 0000000000..6ff394d525 --- /dev/null +++ b/src/perf/java/rx/subscriptions/CompositeSubscriptionPerf.java @@ -0,0 +1,121 @@ +/** + * 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 rx.subscriptions; + +import java.util.concurrent.TimeUnit; + +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 org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; + +import rx.Subscription; + +/** + * Benchmark typical composite subscription single-threaded behavior. + *

+ * gradlew benchmarks "-Pjmh=-f 1 -tu s -bm thrpt -wi 5 -i 5 -r 1 .*CompositeSubscriptionPerf.*" + *

+ * gradlew benchmarks "-Pjmh=-f 1 -tu ns -bm avgt -wi 5 -i 5 -r 1 .*CompositeSubscriptionPerf.*" + */ +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.SECONDS) +public class CompositeSubscriptionPerf { + @State(Scope.Thread) + public static class TheState { + @Param({ "1", "1000", "100000" }) + public int loop; + @Param({ "1", "5", "10", "100" }) + public int count; + + public final CompositeSubscription csub = new CompositeSubscription(); + + public Subscription[] values; + @Setup + public void setup() { + values = new Subscription[count]; + for (int i = 0; i < count; i++) { + values[i] = new Subscription() { + @Override + public boolean isUnsubscribed() { + return false; + } + @Override + public void unsubscribe() { + + } + }; + } + } + } + @Benchmark + public void addRemove(TheState state) { + CompositeSubscription csub = state.csub; + Subscription[] values = state.values; + + for (int i = state.loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.add(state.values[j]); + } + for (int j = values.length - 1; j >= 0; j--) { + csub.remove(state.values[j]); + } + } + } + @Benchmark + public void addRemoveLocal(TheState state) { + CompositeSubscription csub = new CompositeSubscription(); + Subscription[] values = state.values; + + for (int i = state.loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.add(state.values[j]); + } + for (int j = values.length - 1; j >= 0; j--) { + csub.remove(state.values[j]); + } + } + } + @Benchmark + public void addClear(TheState state) { + CompositeSubscription csub = state.csub; + Subscription[] values = state.values; + + for (int i = state.loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.add(state.values[j]); + } + csub.clear(); + } + } + @Benchmark + public void addClearLocal(TheState state) { + CompositeSubscription csub = new CompositeSubscription(); + Subscription[] values = state.values; + + for (int i = state.loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.add(state.values[j]); + } + csub.clear(); + } + } +} diff --git a/src/perf/java/rx/subscriptions/MultipleAssignmentSubscriptionPerf.java b/src/perf/java/rx/subscriptions/MultipleAssignmentSubscriptionPerf.java new file mode 100644 index 0000000000..1623c7d781 --- /dev/null +++ b/src/perf/java/rx/subscriptions/MultipleAssignmentSubscriptionPerf.java @@ -0,0 +1,91 @@ +/** + * 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 rx.subscriptions; + +import java.util.concurrent.TimeUnit; + +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 org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; + +import rx.Subscription; + +/** + * Benchmark typical multiple-assignment subscription behavior. + *

+ * gradlew benchmarks "-Pjmh=-f 1 -tu s -bm thrpt -wi 5 -i 5 -r 1 .*MultipleAssignmentSubscriptionPerf.*" + *

+ * gradlew benchmarks "-Pjmh=-f 1 -tu ns -bm avgt -wi 5 -i 5 -r 1 .*MultipleAssignmentSubscriptionPerf.*" + */ +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.SECONDS) +public class MultipleAssignmentSubscriptionPerf { + @State(Scope.Thread) + public static class TheState { + @Param({ "1", "1000", "100000" }) + public int loop; + @Param({ "1", "5", "10", "100" }) + public int count; + + public final MultipleAssignmentSubscription csub = new MultipleAssignmentSubscription(); + + public Subscription[] values; + @Setup + public void setup() { + values = new Subscription[count]; + for (int i = 0; i < count; i++) { + values[i] = new Subscription() { + @Override + public boolean isUnsubscribed() { + return false; + } + @Override + public void unsubscribe() { + + } + }; + } + } + } + @Benchmark + public void add(TheState state) { + MultipleAssignmentSubscription csub = state.csub; + Subscription[] values = state.values; + + for (int i = state.loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.set(state.values[j]); + } + } + } + @Benchmark + public void addLocal(TheState state) { + MultipleAssignmentSubscription csub = new MultipleAssignmentSubscription(); + Subscription[] values = state.values; + + for (int i = state.loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.set(state.values[j]); + } + } + } +} diff --git a/src/perf/java/rx/subscriptions/SerialSubscriptionPerf.java b/src/perf/java/rx/subscriptions/SerialSubscriptionPerf.java new file mode 100644 index 0000000000..a8103d917e --- /dev/null +++ b/src/perf/java/rx/subscriptions/SerialSubscriptionPerf.java @@ -0,0 +1,91 @@ +/** + * 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 rx.subscriptions; + +import java.util.concurrent.TimeUnit; + +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 org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; + +import rx.Subscription; + +/** + * Benchmark typical serial subscription behavior. + *

+ * gradlew benchmarks "-Pjmh=-f 1 -tu s -bm thrpt -wi 5 -i 5 -r 1 .*SerialSubscriptionPerf.*" + *

+ * gradlew benchmarks "-Pjmh=-f 1 -tu ns -bm avgt -wi 5 -i 5 -r 1 .*SerialSubscriptionPerf.*" + */ +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.SECONDS) +public class SerialSubscriptionPerf { + @State(Scope.Thread) + public static class TheState { + @Param({ "1", "1000", "100000" }) + public int loop; + @Param({ "1", "5", "10", "100" }) + public int count; + + public final SerialSubscription csub = new SerialSubscription(); + + public Subscription[] values; + @Setup + public void setup() { + values = new Subscription[count]; + for (int i = 0; i < count; i++) { + values[i] = new Subscription() { + @Override + public boolean isUnsubscribed() { + return false; + } + @Override + public void unsubscribe() { + + } + }; + } + } + } + @Benchmark + public void add(TheState state) { + SerialSubscription csub = state.csub; + Subscription[] values = state.values; + + for (int i = state.loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.set(state.values[j]); + } + } + } + @Benchmark + public void addLocal(TheState state) { + SerialSubscription csub = new SerialSubscription(); + Subscription[] values = state.values; + + for (int i = state.loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.set(state.values[j]); + } + } + } +} diff --git a/src/perf/java/rx/subscriptions/SubscriptionListConcurrentPerf.java b/src/perf/java/rx/subscriptions/SubscriptionListConcurrentPerf.java new file mode 100644 index 0000000000..93c7438f2c --- /dev/null +++ b/src/perf/java/rx/subscriptions/SubscriptionListConcurrentPerf.java @@ -0,0 +1,131 @@ +/** + * 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 rx.subscriptions; + +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Group; +import org.openjdk.jmh.annotations.GroupThreads; +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 rx.Subscription; +import rx.internal.util.SubscriptionList; + +/** + * Benchmark typical subscription list concurrent behavior. + *

+ * gradlew benchmarks "-Pjmh=-f 1 -tu s -bm thrpt -wi 5 -i 5 -r 1 .*CompositeSubscriptionConcurrentPerf.*" + *

+ * gradlew benchmarks "-Pjmh=-f 1 -tu ns -bm avgt -wi 5 -i 5 -r 1 .*CompositeSubscriptionConcurrentPerf.*" + */ +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.SECONDS) +@Threads(2) +@State(Scope.Group) +public class SubscriptionListConcurrentPerf { + @Param({ "1", "1000", "100000" }) + public int loop; + + public final SubscriptionList csub = new SubscriptionList(); + @Param({ "1", "5", "10", "20" }) + public int count; + + public Subscription[] values; + @Setup + public void setup() { + values = new Subscription[count * 2]; + for (int i = 0; i < count * 2; i++) { + values[i] = new Subscription() { + @Override + public boolean isUnsubscribed() { + return false; + } + @Override + public void unsubscribe() { + + } + }; + } + } + + @Group("g1") + @GroupThreads(1) + @Benchmark + public void addClearT1() { + SubscriptionList csub = this.csub; + Subscription[] values = this.values; + + for (int i = loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.add(values[j]); + } + csub.clear(); + } + } + @Group("g1") + @GroupThreads(1) + @Benchmark + public void addClearT2() { + SubscriptionList csub = this.csub; + Subscription[] values = this.values; + + for (int i = loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.add(values[j]); + } + csub.clear(); + } + } + @Group("g2") + @GroupThreads(1) + @Benchmark + public void addClearHalfT1() { + SubscriptionList csub = this.csub; + Subscription[] values = this.values; + int n = values.length; + + for (int i = loop; i > 0; i--) { + for (int j = n / 2 - 1; j >= 0; j--) { + csub.add(values[j]); + } + csub.clear(); + } + } + @Group("g2") + @GroupThreads(1) + @Benchmark + public void addRemoveHalfT2() { + SubscriptionList csub = this.csub; + Subscription[] values = this.values; + int n = values.length; + + for (int i = loop; i > 0; i--) { + for (int j = n - 1; j >= n / 2; j--) { + csub.add(values[j]); + } + csub.clear(); + } + } +} diff --git a/src/perf/java/rx/subscriptions/SubscriptionListPerf.java b/src/perf/java/rx/subscriptions/SubscriptionListPerf.java new file mode 100644 index 0000000000..02b7b467d2 --- /dev/null +++ b/src/perf/java/rx/subscriptions/SubscriptionListPerf.java @@ -0,0 +1,94 @@ +/** + * 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 rx.subscriptions; + +import java.util.concurrent.TimeUnit; + +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 org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; + +import rx.Subscription; +import rx.internal.util.SubscriptionList; + +/** + * Benchmark typical subscription list behavior. + *

+ * gradlew benchmarks "-Pjmh=-f 1 -tu s -bm thrpt -wi 5 -i 5 -r 1 .*SubscriptionListPerf.*" + *

+ * gradlew benchmarks "-Pjmh=-f 1 -tu ns -bm avgt -wi 5 -i 5 -r 1 .*SubscriptionListPerf.*" + */ +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.SECONDS) +public class SubscriptionListPerf { + @State(Scope.Thread) + public static class TheState { + @Param({ "1", "1000", "100000" }) + public int loop; + @Param({ "1", "5", "10", "100" }) + public int count; + + public final SubscriptionList csub = new SubscriptionList(); + + public Subscription[] values; + @Setup + public void setup() { + values = new Subscription[count]; + for (int i = 0; i < count; i++) { + values[i] = new Subscription() { + @Override + public boolean isUnsubscribed() { + return false; + } + @Override + public void unsubscribe() { + + } + }; + } + } + } + @Benchmark + public void addClear(TheState state) { + SubscriptionList csub = state.csub; + Subscription[] values = state.values; + + for (int i = state.loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.add(state.values[j]); + } + csub.clear(); + } + } + @Benchmark + public void addClearLocal(TheState state) { + SubscriptionList csub = new SubscriptionList(); + Subscription[] values = state.values; + + for (int i = state.loop; i > 0; i--) { + for (int j = values.length - 1; j >= 0; j--) { + csub.add(state.values[j]); + } + csub.clear(); + } + } +} From 7163288b11a67ddf6a155b7af4916d6b206a688e Mon Sep 17 00:00:00 2001 From: akarnokd Date: Tue, 3 Feb 2015 08:28:16 +0100 Subject: [PATCH 2/2] Fixed local variables, added blackhole to *Local benchmarks --- .../CompositeSubscriptionPerf.java | 29 +++++++++---------- .../MultipleAssignmentSubscriptionPerf.java | 17 ++++------- .../subscriptions/SerialSubscriptionPerf.java | 17 ++++------- .../subscriptions/SubscriptionListPerf.java | 17 ++++------- 4 files changed, 31 insertions(+), 49 deletions(-) diff --git a/src/perf/java/rx/subscriptions/CompositeSubscriptionPerf.java b/src/perf/java/rx/subscriptions/CompositeSubscriptionPerf.java index 6ff394d525..bbbd8f1b63 100644 --- a/src/perf/java/rx/subscriptions/CompositeSubscriptionPerf.java +++ b/src/perf/java/rx/subscriptions/CompositeSubscriptionPerf.java @@ -18,14 +18,8 @@ import java.util.concurrent.TimeUnit; -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 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.*; +import org.openjdk.jmh.infra.Blackhole; import rx.Subscription; @@ -73,26 +67,28 @@ public void addRemove(TheState state) { for (int i = state.loop; i > 0; i--) { for (int j = values.length - 1; j >= 0; j--) { - csub.add(state.values[j]); + csub.add(values[j]); } for (int j = values.length - 1; j >= 0; j--) { - csub.remove(state.values[j]); + csub.remove(values[j]); } } } @Benchmark - public void addRemoveLocal(TheState state) { + public void addRemoveLocal(TheState state, Blackhole bh) { CompositeSubscription csub = new CompositeSubscription(); Subscription[] values = state.values; for (int i = state.loop; i > 0; i--) { for (int j = values.length - 1; j >= 0; j--) { - csub.add(state.values[j]); + csub.add(values[j]); } for (int j = values.length - 1; j >= 0; j--) { - csub.remove(state.values[j]); + csub.remove(values[j]); } } + + bh.consume(csub); } @Benchmark public void addClear(TheState state) { @@ -101,21 +97,22 @@ public void addClear(TheState state) { for (int i = state.loop; i > 0; i--) { for (int j = values.length - 1; j >= 0; j--) { - csub.add(state.values[j]); + csub.add(values[j]); } csub.clear(); } } @Benchmark - public void addClearLocal(TheState state) { + public void addClearLocal(TheState state, Blackhole bh) { CompositeSubscription csub = new CompositeSubscription(); Subscription[] values = state.values; for (int i = state.loop; i > 0; i--) { for (int j = values.length - 1; j >= 0; j--) { - csub.add(state.values[j]); + csub.add(values[j]); } csub.clear(); } + bh.consume(csub); } } diff --git a/src/perf/java/rx/subscriptions/MultipleAssignmentSubscriptionPerf.java b/src/perf/java/rx/subscriptions/MultipleAssignmentSubscriptionPerf.java index 1623c7d781..b45a1c4c83 100644 --- a/src/perf/java/rx/subscriptions/MultipleAssignmentSubscriptionPerf.java +++ b/src/perf/java/rx/subscriptions/MultipleAssignmentSubscriptionPerf.java @@ -18,14 +18,8 @@ import java.util.concurrent.TimeUnit; -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 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.*; +import org.openjdk.jmh.infra.Blackhole; import rx.Subscription; @@ -73,19 +67,20 @@ public void add(TheState state) { for (int i = state.loop; i > 0; i--) { for (int j = values.length - 1; j >= 0; j--) { - csub.set(state.values[j]); + csub.set(values[j]); } } } @Benchmark - public void addLocal(TheState state) { + public void addLocal(TheState state, Blackhole bh) { MultipleAssignmentSubscription csub = new MultipleAssignmentSubscription(); Subscription[] values = state.values; for (int i = state.loop; i > 0; i--) { for (int j = values.length - 1; j >= 0; j--) { - csub.set(state.values[j]); + csub.set(values[j]); } } + bh.consume(csub); } } diff --git a/src/perf/java/rx/subscriptions/SerialSubscriptionPerf.java b/src/perf/java/rx/subscriptions/SerialSubscriptionPerf.java index a8103d917e..5f6a275b00 100644 --- a/src/perf/java/rx/subscriptions/SerialSubscriptionPerf.java +++ b/src/perf/java/rx/subscriptions/SerialSubscriptionPerf.java @@ -18,14 +18,8 @@ import java.util.concurrent.TimeUnit; -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 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.*; +import org.openjdk.jmh.infra.Blackhole; import rx.Subscription; @@ -73,19 +67,20 @@ public void add(TheState state) { for (int i = state.loop; i > 0; i--) { for (int j = values.length - 1; j >= 0; j--) { - csub.set(state.values[j]); + csub.set(values[j]); } } } @Benchmark - public void addLocal(TheState state) { + public void addLocal(TheState state, Blackhole bh) { SerialSubscription csub = new SerialSubscription(); Subscription[] values = state.values; for (int i = state.loop; i > 0; i--) { for (int j = values.length - 1; j >= 0; j--) { - csub.set(state.values[j]); + csub.set(values[j]); } } + bh.consume(csub); } } diff --git a/src/perf/java/rx/subscriptions/SubscriptionListPerf.java b/src/perf/java/rx/subscriptions/SubscriptionListPerf.java index 02b7b467d2..ca2240275e 100644 --- a/src/perf/java/rx/subscriptions/SubscriptionListPerf.java +++ b/src/perf/java/rx/subscriptions/SubscriptionListPerf.java @@ -18,14 +18,8 @@ import java.util.concurrent.TimeUnit; -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 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.*; +import org.openjdk.jmh.infra.Blackhole; import rx.Subscription; import rx.internal.util.SubscriptionList; @@ -74,21 +68,22 @@ public void addClear(TheState state) { for (int i = state.loop; i > 0; i--) { for (int j = values.length - 1; j >= 0; j--) { - csub.add(state.values[j]); + csub.add(values[j]); } csub.clear(); } } @Benchmark - public void addClearLocal(TheState state) { + public void addClearLocal(TheState state, Blackhole bh) { SubscriptionList csub = new SubscriptionList(); Subscription[] values = state.values; for (int i = state.loop; i > 0; i--) { for (int j = values.length - 1; j >= 0; j--) { - csub.add(state.values[j]); + csub.add(values[j]); } csub.clear(); } + bh.consume(csub); } }