You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by jw...@apache.org on 2017/07/16 18:56:44 UTC

groovy git commit: add JMH to performance subproject (closes #573)

Repository: groovy
Updated Branches:
  refs/heads/master 24ce80ada -> f89b21d4c


add JMH to performance subproject (closes #573)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/f89b21d4
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/f89b21d4
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/f89b21d4

Branch: refs/heads/master
Commit: f89b21d4c445841cf6845f9f932d167e296060cb
Parents: 24ce80a
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Jul 9 11:49:55 2017 -0700
Committer: John Wagenleitner <jw...@apache.org>
Committed: Sun Jul 16 11:52:43 2017 -0700

----------------------------------------------------------------------
 build.gradle                                    |   3 +-
 subprojects/performance/README.adoc             |  39 +++++
 subprojects/performance/build.gradle            |  13 ++
 .../groovy/bench/dispatch/CallsiteBench.java    | 146 +++++++++++++++++++
 .../groovy/bench/dispatch/Callsite.groovy       |  29 ++++
 5 files changed, 229 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/f89b21d4/build.gradle
----------------------------------------------------------------------
diff --git a/build.gradle b/build.gradle
index e7ddd6f..10edd49 100644
--- a/build.gradle
+++ b/build.gradle
@@ -455,7 +455,8 @@ allprojects {
                 rootProject.bootstrapJar.archivePath
         )
 
-        classpath = classpath + groovyClasspath
+        // TODO: this null check was required after adding JMH plugin to performance project
+        classpath = (classpath != null) ? classpath + groovyClasspath : groovyClasspath
     }
 
     if (useIndy()) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/f89b21d4/subprojects/performance/README.adoc
----------------------------------------------------------------------
diff --git a/subprojects/performance/README.adoc b/subprojects/performance/README.adoc
new file mode 100644
index 0000000..c134f15
--- /dev/null
+++ b/subprojects/performance/README.adoc
@@ -0,0 +1,39 @@
+//////////////////////////////////////////
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+
+//////////////////////////////////////////
+
+= Performance
+
+This subproject contains two sets of performance related tests.  The first
+are compiler tests that can be run using the following Gradle task:
+
+    ./gradlew :perf:performanceTests
+
+This will compile various source files using several past versions of Apache
+Groovy in addition to the current source version.
+
+This subproject also contains `JMH` Benchmarks which can be run using:
+
+    ./gradlew :perf:jmh
+
+In order to run the benchmarks against InvokeDynamic generated classes use
+the `indy` property:
+
+    ./gradlew -Pindy=true :perf:jmh

http://git-wip-us.apache.org/repos/asf/groovy/blob/f89b21d4/subprojects/performance/build.gradle
----------------------------------------------------------------------
diff --git a/subprojects/performance/build.gradle b/subprojects/performance/build.gradle
index 0a2681b..bf30ff3 100644
--- a/subprojects/performance/build.gradle
+++ b/subprojects/performance/build.gradle
@@ -19,16 +19,29 @@
 
 import java.text.DecimalFormat
 
+plugins {
+    id "me.champeau.gradle.jmh" version "0.4.2"
+}
+
 configurations {
     stats
     testCompile.extendsFrom(stats)
 }
 
 dependencies {
+    jmh rootProject
     testCompile 'org.codehaus.groovy:groovy:2.4.7'
     stats 'org.apache.commons:commons-math3:3.6'
 }
 
+jmh {
+    jmhVersion = '1.19'
+    include = ['.*']
+    includeTests = true
+    resultsFile = project.file("target/results${useIndy() ? '_indy' : ''}.txt")
+}
+jmhClasses.dependsOn clean
+
 sourceCompatibility = 1.8
 targetCompatibility = 1.8
 

http://git-wip-us.apache.org/repos/asf/groovy/blob/f89b21d4/subprojects/performance/src/jmh/java/org/apache/groovy/bench/dispatch/CallsiteBench.java
----------------------------------------------------------------------
diff --git a/subprojects/performance/src/jmh/java/org/apache/groovy/bench/dispatch/CallsiteBench.java b/subprojects/performance/src/jmh/java/org/apache/groovy/bench/dispatch/CallsiteBench.java
new file mode 100644
index 0000000..c6b0b80
--- /dev/null
+++ b/subprojects/performance/src/jmh/java/org/apache/groovy/bench/dispatch/CallsiteBench.java
@@ -0,0 +1,146 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 org.apache.groovy.bench.dispatch;
+
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.util.Arrays;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@Warmup(iterations = 5, time = 2, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 5, time = 2, timeUnit = TimeUnit.SECONDS)
+@Fork(3)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+public class CallsiteBench {
+
+    @Benchmark
+    public void dispatch_1_monomorphic_groovy(MonomorphicState state, Blackhole bh) {
+        Callsite.dispatch(state.receivers, bh);
+    }
+
+    @Benchmark
+    public void dispatch_1_monomorphic_java(MonomorphicState state, Blackhole bh) {
+        dispatch(state.receivers, bh);
+    }
+
+    @Benchmark
+    public void dispatch_3_polymorphic_groovy(PolymorphicState state, Blackhole bh) {
+        Callsite.dispatch(state.receivers, bh);
+    }
+
+    @Benchmark
+    public void dispatch_3_polymorphic_java(PolymorphicState state, Blackhole bh) {
+        dispatch(state.receivers, bh);
+    }
+
+    @Benchmark
+    public void dispatch_8_megamorphic_groovy(MegamorphicState state, Blackhole bh) {
+        Callsite.dispatch(state.receivers, bh);
+    }
+
+    @Benchmark
+    public void dispatch_8_megamorphic_java(MegamorphicState state, Blackhole bh) {
+        dispatch(state.receivers, bh);
+    }
+
+    private void dispatch(Object[] receivers, Blackhole bh) {
+        for (Object receiver : receivers) {
+            bh.consume(receiver.toString());
+        }
+    }
+
+    private static final int RECEIVER_COUNT = 64;
+
+    private static final Object[] RECEIVERS = new Object[] {
+            new Receiver1(), new Receiver2(), new Receiver3(), new Receiver4(),
+            new Receiver5(), new Receiver6(), new Receiver7(), new Receiver8()
+    };
+
+    @State(Scope.Thread)
+    public static class MonomorphicState {
+        Object[] receivers;
+        @Setup(Level.Trial)
+        public void setUp() {
+            receivers = new Object[RECEIVER_COUNT];
+            Arrays.fill(receivers, RECEIVERS[0]);
+        }
+    }
+
+    @State(Scope.Thread)
+    public static class PolymorphicState {
+        final Random random = new Random();
+        Object[] receivers;
+        @Setup(Level.Iteration)
+        public void setUp() {
+            receivers = new Object[RECEIVER_COUNT];
+            for (int i = 0; i < RECEIVER_COUNT; i++) {
+                receivers[i] = RECEIVERS[random.nextInt(3)];
+            }
+        }
+    }
+
+    @State(Scope.Thread)
+    public static class MegamorphicState {
+        final Random random = new Random();
+        Object[] receivers;
+        @Setup(Level.Iteration)
+        public void setUp() {
+            receivers = new Object[RECEIVER_COUNT];
+            for (int i = 0; i < RECEIVER_COUNT; i++) {
+                receivers[i] = RECEIVERS[random.nextInt(8)];
+            }
+        }
+    }
+
+    private static class Receiver1 {
+        @Override public String toString() { return "receiver1"; }
+    }
+
+    private static class Receiver2 {
+        @Override public String toString() { return "receiver2"; }
+    }
+
+    private static class Receiver3 {
+        @Override public String toString() { return "receiver3"; }
+    }
+
+    private static class Receiver4 {
+        @Override public String toString() { return "receiver4"; }
+    }
+
+    private static class Receiver5 {
+        @Override public String toString() { return "receiver5"; }
+    }
+
+    private static class Receiver6 {
+        @Override public String toString() { return "receiver6"; }
+    }
+
+    private static class Receiver7 {
+        @Override public String toString() { return "receiver7"; }
+    }
+
+    private static class Receiver8 {
+        @Override public String toString() { return "receiver8"; }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/f89b21d4/subprojects/performance/src/test/groovy/org/apache/groovy/bench/dispatch/Callsite.groovy
----------------------------------------------------------------------
diff --git a/subprojects/performance/src/test/groovy/org/apache/groovy/bench/dispatch/Callsite.groovy b/subprojects/performance/src/test/groovy/org/apache/groovy/bench/dispatch/Callsite.groovy
new file mode 100644
index 0000000..2d0bc19
--- /dev/null
+++ b/subprojects/performance/src/test/groovy/org/apache/groovy/bench/dispatch/Callsite.groovy
@@ -0,0 +1,29 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 org.apache.groovy.bench.dispatch
+
+class Callsite {
+
+    static void dispatch(Object[] receivers, bh) {
+        for (Object receiver : receivers) {
+            bh.consume(receiver.toString())
+        }
+    }
+
+}