/*
* Copyright 2012-2016 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
*
* 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 org.gololang.microbenchmarks.fibonacci;
import clojure.lang.Var;
import org.gololang.microbenchmarks.support.CodeLoader;
import org.gololang.microbenchmarks.support.JRubyContainerAndReceiver;
import org.openjdk.jmh.annotations.*;
import org.python.core.PyFunction;
import org.python.core.PyLong;
import org.python.util.PythonInterpreter;
import javax.script.Invocable;
import java.lang.invoke.MethodHandle;
import java.util.concurrent.TimeUnit;
import static java.lang.invoke.MethodType.genericMethodType;
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class FibonacciMicroBenchmark {
@State(Scope.Thread)
static public class State40 {
long n = 40L;
}
@State(Scope.Thread)
static public class State30 {
long n = 30L;
}
@State(Scope.Thread)
static public class GoloState {
MethodHandle fib;
@Setup(Level.Trial)
public void prepare() {
fib = new CodeLoader().golo("fibonacci", "fib", 1);
}
}
@State(Scope.Thread)
static public class GroovyState {
MethodHandle fib;
@Setup(Level.Trial)
public void prepare() {
fib = new CodeLoader().groovy("Fibonacci", "fib", genericMethodType(1));
}
}
@State(Scope.Thread)
static public class GroovyIndyState {
MethodHandle fib;
@Setup(Level.Trial)
public void prepare() {
fib = new CodeLoader().groovy_indy("Fibonacci", "fib", genericMethodType(1));
}
}
@State(Scope.Thread)
static public class ClojureState {
Var fib;
@Setup(Level.Trial)
public void prepare() {
fib = new CodeLoader().clojure("fibonacci", "fibonacci", "fib");
}
}
@State(Scope.Thread)
static public class JRubyState {
JRubyContainerAndReceiver containerAndReceiver;
@Setup(Level.Trial)
public void prepare() {
containerAndReceiver = new CodeLoader().jruby("fibonacci");
}
}
@State(Scope.Thread)
static public class NashornState {
Invocable invocable;
@Setup(Level.Trial)
public void prepare() {
invocable = (Invocable) new CodeLoader().nashorn("fibonacci");
}
}
@State(Scope.Thread)
static public class JythonState {
PyFunction fib;
@Setup(Level.Trial)
public void prepare() {
CodeLoader loader = new CodeLoader();
PythonInterpreter interpreter = loader.jython("fibonacci");
fib = (PyFunction) interpreter.get("fib");
}
}
/* ................................................................................................................ */
@Benchmark
public long baseline_java_30(State30 state) {
return JavaRecursiveFibonacci.withPrimitives(state.n);
}
@Benchmark
public long baseline_java_boxing_30(State30 state) {
return JavaRecursiveFibonacci.withBoxing(state.n);
}
@Benchmark
public Object golo_30(State30 state30, GoloState goloState) throws Throwable {
return goloState.fib.invokeExact((Object) state30.n);
}
@Benchmark
public Object groovy_30(State30 state30, GroovyState groovyState) throws Throwable {
return groovyState.fib.invokeExact((Object) state30.n);
}
@Benchmark
public Object groovy_indy_30(State30 state30, GroovyIndyState groovyState) throws Throwable {
return groovyState.fib.invokeExact((Object) state30.n);
}
@Benchmark
public Object clojure_30(State30 state30, ClojureState clojureState) {
return clojureState.fib.invoke(state30.n);
}
@Benchmark
public Object jruby_30(State30 state30, JRubyState jRubyState) {
return jRubyState.containerAndReceiver.container()
.callMethod(jRubyState.containerAndReceiver.receiver(), "fib", state30.n, Long.class);
}
@Benchmark
public Object nashorn_30(State30 state30, NashornState nashornState) throws Throwable {
return nashornState.invocable.invokeFunction("fib", state30.n);
}
@Benchmark
public Object jython_30(State30 state30, JythonState jythonState) throws Throwable {
return jythonState.fib.__call__(new PyLong(state30.n));
}
/* ................................................................................................................ */
@Benchmark
public long baseline_java_40(State40 state) {
return JavaRecursiveFibonacci.withPrimitives(state.n);
}
@Benchmark
public long baseline_java_boxing_40(State40 state) {
return JavaRecursiveFibonacci.withBoxing(state.n);
}
@Benchmark
public Object golo_40(State40 state40, GoloState goloState) throws Throwable {
return goloState.fib.invokeExact((Object) state40.n);
}
@Benchmark
public Object groovy_40(State40 state40, GroovyState groovyState) throws Throwable {
return groovyState.fib.invokeExact((Object) state40.n);
}
@Benchmark
public Object groovy_indy_40(State40 state40, GroovyIndyState groovyState) throws Throwable {
return groovyState.fib.invokeExact((Object) state40.n);
}
@Benchmark
public Object clojure_40(State40 state40, ClojureState clojureState) {
return clojureState.fib.invoke(state40.n);
}
@Benchmark
public Object jruby_40(State40 state40, JRubyState jRubyState) {
return jRubyState.containerAndReceiver.container()
.callMethod(jRubyState.containerAndReceiver.receiver(), "fib", state40.n, Long.class);
}
@Benchmark
public Object nashorn_40(State40 state40, NashornState nashornState) throws Throwable {
return nashornState.invocable.invokeFunction("fib", state40.n);
}
// Disabled, too slow
// @Benchmark
public Object jython_40(State40 state40, JythonState jythonState) throws Throwable {
return jythonState.fib.__call__(new PyLong(state40.n));
}
}