Skip to content

Instantly share code, notes, and snippets.

@nobeans
Created April 8, 2012 14:11
Show Gist options
  • Save nobeans/2337510 to your computer and use it in GitHub Desktop.
Save nobeans/2337510 to your computer and use it in GitHub Desktop.
Summarized and translated my tweets about groovy at 2012-04-07
When I decompiled a compiled code with @CompileStatic, I found something there:
- @TypeChecked annotations there. (it's good)
- compareTo was compiled as primitive code instead of a call of ScriptBytecodeAdapter.
- There are unnecessary null in places.
- The decompiled result seems curious. It's a little inefficient.
- By Groovy++: (right.getColor()==BLACK)
- By Groovy2.0b @CompileStatic: ((right.color==BLACK ? 1 : 0) !=0)
--------------
Groovy source:
--------------
import groovy.transform.CompileStatic
@CompileStatic
class Simple {
def method(int a, int b, int c) {
if (a == 1 || b == 1 || c == 1) {
return true
}
return false
}
}
--------------
Decompiled of the class copmiled with CompileStatic:
--------------
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import groovy.transform.TypeChecked.TypeCheckingInfo;
public class Simple
implements GroovyObject
{
public Simple()
{
Simple this;
MetaClass localMetaClass = $getStaticMetaClass();
this.metaClass = localMetaClass;
}
@TypeChecked.TypeCheckingInfo(inferredType="AAlDbGFzc05vZGUAAAFaAP////8=", version=1)
public Object method(int a, int b, int c)
{
if (((a == 1) ? 1 : 0) == 0);
if (((((b == 1) ? 1 : 0) != 0) ? 1 : 0) == 0);
if (((((c == 1) ? 1 : 0) != 0) ? 1 : 0) != 0) { //------[1]
return Boolean.valueOf(true);
}
return Boolean.valueOf(false); return null; // ----[2]
}
static
{
__$swapInit();
long l1 = 0L;
__timeStamp__239_neverHappen1333898122602 = l1;
long l2 = 1333898122602L;
__timeStamp = l2;
}
}
--------------
Tests
--------------
import spock.lang.*
class SimpleSpec extends Specification {
def simple
def setup() {
simple = new Simple()
}
def ""() {
expect:
simple.method(a, b, c) == result
where:
a | b | c | result
0 | 0 | 0 | false
0 | 0 | 1 | true
0 | 1 | 1 | true
1 | 1 | 1 | true
1 | 0 | 0 | true
0 | 1 | 0 | true
0 | 0 | 1 | true
}
}
--------------
[1] is the very curious, but tests are all green...
2nd return of [2] is unnecessary.
***
A performance of latest HEAD of master (0c2b64) without indy option is almost as same as released 1.8.6.
@StaticCompile's performance is ten times faster than them, and almost as same as Groovy++'s one. It's great work!
And now, I don't know the usage of indy option...
@melix
Copy link

melix commented Apr 8, 2012

Excellent feedback! Thank you. I'll check that after my holidays :-)

@nobeans
Copy link
Author

nobeans commented Apr 9, 2012

ok. enjoy your holidays!

another feedback from nahi's tweet: https://twitter.com/#!/nahi/status/189258468304228353
I met the same error too.

@nobeans
Copy link
Author

nobeans commented Apr 9, 2012

It seemed just failing to make jar file, so I tried to do "cd target/staging; jar cvf groovy-all.jar." It succeeded and I could do benchmark with the jar file.

but I didn't how to specify --indy option for groovy/groovyc command via gradle. So I changed the groovy-core code to always use indy option:

commit 85dc33e4fcdc86b1f690d0f787d6f4a632e816f8
Author: Yasuharu NAKANO 
Date:   Mon Apr 9 21:08:50 2012 +0900

    default set useIndy option

diff --git a/src/main/groovy/ui/GroovyMain.java b/src/main/groovy/ui/GroovyMain.java
index 219ca48..6e19118 100644
--- a/src/main/groovy/ui/GroovyMain.java
+++ b/src/main/groovy/ui/GroovyMain.java
@@ -321,9 +321,9 @@ public class GroovyMain {
             main.conf.getOptimizationOptions().put(deopt_i,false);
         }
         
-        if (line.hasOption("indy")) {
+//        if (line.hasOption("indy")) {
             main.conf.getOptimizationOptions().put("indy", true);
-        }
+//        }
         
         main.args = args;
 
diff --git a/src/main/org/codehaus/groovy/ant/Groovyc.java b/src/main/org/codehaus/groovy/ant/Groovyc.java
index 97a9080..d08d37f 100644
--- a/src/main/org/codehaus/groovy/ant/Groovyc.java
+++ b/src/main/org/codehaus/groovy/ant/Groovyc.java
@@ -847,9 +847,9 @@ public class Groovyc extends MatchingTask {
         if (stacktrace) {
             commandLineList.add("-e");
         }
-        if (useIndy) {
+//        if (useIndy) {
             commandLineList.add("-indy");
-        }
+//        }
     }
 
     private void addSourceFiles(List commandLineList) {

When I did benchmark with the jar on snow leopard with jdk 1.7.0-preview, it worked but the performance was ten times slower than the one without indy.

When I did benchmark with the same jar on lion with jdk 1.7.0_04-ea-b19, the following exception occured:

$ ./gradlew bench
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:benchmarkPicked up _JAVA_OPTIONS: -Dfile.encoding=utf-8 -Xms128m -Xmx1024m
Exception in thread "main" java.lang.NoClassDefFoundError: org/jggug/javaonetokyo/bof/bench/Node
    at java.lang.invoke.MethodHandle.invokeExact(MethodHandle.java)
    at java.lang.invoke.MethodHandle.invokeExact(MethodHandle.java)
    at org.jggug.javaonetokyo.bof.bench.Node.balanceRight(RBTreeMap.groovy:136)
    at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1303)
    at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1289)
    at java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L2(MethodHandleImpl.java:1130)
    at org.jggug.javaonetokyo.bof.bench.Node.put(RBTreeMap.groovy:53)
    at java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L3(MethodHandleImpl.java:1138)
    at org.jggug.javaonetokyo.bof.bench.Node.put(RBTreeMap.groovy:52)
    at java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L3(MethodHandleImpl.java:1138)
    at org.jggug.javaonetokyo.bof.bench.Node.put(RBTreeMap.groovy:52)
    at java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L3(MethodHandleImpl.java:1138)
    at org.jggug.javaonetokyo.bof.bench.Node.put(RBTreeMap.groovy:48)
    at java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L3(MethodHandleImpl.java:1138)
    at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:685)
    at org.jggug.javaonetokyo.bof.bench.Node.put(RBTreeMap.groovy:52)
    at java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L3(MethodHandleImpl.java:1138)
    at org.jggug.javaonetokyo.bof.bench.RBTreeMap.put(RBTreeMap.groovy:12)
    at java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L3(MethodHandleImpl.java:1138)
    at org.jggug.javaonetokyo.bof.bench.Benchmark$_putAndGet_closure2.doCall(Benchmark.groovy:23)
    at sun.reflect.GeneratedMethodAccessor6.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:900)
    at groovy.lang.Closure.call(Closure.java:412)
    at groovy.lang.Closure.call(Closure.java:425)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.callClosureForLine(DefaultGroovyMethods.java:3656)
    at org.codehaus.groovy.runtime.IOGroovyMethods.eachLine(IOGroovyMethods.java:401)
    at org.codehaus.groovy.runtime.ResourceGroovyMethods.eachLine(ResourceGroovyMethods.java:244)
    at org.codehaus.groovy.runtime.ResourceGroovyMethods.eachLine(ResourceGroovyMethods.java:210)
    at org.codehaus.groovy.runtime.dgm$724.invoke(Unknown Source)
    at java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L2(MethodHandleImpl.java:1130)
    at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:685)
    at org.jggug.javaonetokyo.bof.bench.Benchmark.putAndGet(Benchmark.groovy:21)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1303)
    at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1289)
    at java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L2(MethodHandleImpl.java:1130)
    at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:685)
    at org.jggug.javaonetokyo.bof.bench.Benchmark$_main_closure4_closure5_closure6.doCall(Benchmark.groovy:50)
    at org.jggug.javaonetokyo.bof.bench.Benchmark$_main_closure4_closure5_closure6.doCall(Benchmark.groovy)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:900)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
    at gbench.Benchmarker.computeExecutionTimes(Benchmarker.groovy:77)
    at gbench.Benchmarker.this$2$computeExecutionTimes(Benchmarker.groovy)
    at gbench.Benchmarker$this$2$computeExecutionTimes.callCurrent(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
    at gbench.Benchmarker.run(Benchmarker.groovy:112)
    at gbench.Benchmarker$run.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
    at gbench.BenchmarkBuilder.with(BenchmarkBuilder.groovy:149)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:361)
    at java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L3(MethodHandleImpl.java:1138)
    at java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L3(MethodHandleImpl.java:1138)
    at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:685)
    at org.jggug.javaonetokyo.bof.bench.Benchmark$_main_closure4_closure5.doCall(Benchmark.groovy:49)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:900)
    at groovy.lang.Closure.call(Closure.java:412)
    at groovy.lang.Closure.call(Closure.java:425)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.times(DefaultGroovyMethods.java:9755)
    at org.codehaus.groovy.runtime.dgm$483.invoke(Unknown Source)
    at java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L2(MethodHandleImpl.java:1130)
    at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:685)
    at org.jggug.javaonetokyo.bof.bench.Benchmark$_main_closure4.doCall(Benchmark.groovy:48)
    at org.jggug.javaonetokyo.bof.bench.Benchmark$_main_closure4.doCall(Benchmark.groovy)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:900)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
    at gbench.BenchmarkBuilder.doRun(BenchmarkBuilder.groovy:90)
    at gbench.BenchmarkBuilder.this$2$doRun(BenchmarkBuilder.groovy)
    at gbench.BenchmarkBuilder$this$2$doRun.callCurrent(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
    at gbench.BenchmarkBuilder.run(BenchmarkBuilder.groovy:83)
    at java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L3(MethodHandleImpl.java:1138)
    at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:685)
    at org.jggug.javaonetokyo.bof.bench.Benchmark.main(Benchmark.groovy:47)


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':benchmark'.
> Command '/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home/bin/java' finished with (non-zero) exit value 1.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 7.869 secs

I tried to build again on lion with jdk 1.7.0_04-ea-b19, but the same error occurred.

@glaforge
Copy link

This NoClassDefFoundError might be related to some bugs in the JDK. I've seen that mentioned by some other language implementors on the mlvn-dev mailing-list. It might be fixed in some Open JDK source tree somewhere.
Someone mentioned to put the offending code on the boot classpath. So if you bundle your benchmark in a JAR, you could add that JAR on the bootclasspath with -Xbootclasspath/a:mybench.jar.
I'd be curious to know if it helps.

@blackdrag
Copy link

Benchmarking indy with jdk7 is always to be taken with a grain of salt. Eevry update changes the numbers, since optimization work is still going on in that area in the jdk. update 1 for example was horribly slow. I think I did also read about some class loading problems that are supposed to be fixed in update 3 or 4. Even if it is not so easy to do I encourage you to test the same program using different jdk versions, because should there be an error appearing in only one of them, then you can be sure to have found a jdk bug (which may happen from time to time in combination with indy, this is really bleeding edge here ;)) . Should it appear in all versions, then it might be a bug in Groovy

@glaforge
Copy link

By the way, running another unrelated benchmark just minutes ago, and I also got a similar NoClassDefFoundError with:

$ java -version
java version "1.7.0_04-ea"
Java(TM) SE Runtime Environment (build 1.7.0_04-ea-b17)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b18, mixed mode)

@nobeans
Copy link
Author

nobeans commented Apr 11, 2012

Thanks for the nice information > glaforge

I've just run the benchmark with "-Xbootclasspath/a:build/classes/main:libs/groovy-all.jar" option. I could avoid the NoClassDefFoundError! but another error occurred...

java.lang.NullPointerException
        at org.codehaus.groovy.reflection.GeneratedMetaMethod$DgmMethodRecord.loadDgmInfo(GeneratedMetaMethod.java:163)
        at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.registerMethods(MetaClassRegistryImpl.java:156)
        at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.(MetaClassRegistryImpl.java:83)
        at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.(MetaClassRegistryImpl.java:61)
        at groovy.lang.GroovySystem.(GroovySystem.java:29)
        at org.codehaus.groovy.vmplugin.v7.IndyInterface.getMetaClass(IndyInterface.java:182)
        at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:667)
        at org.jggug.javaonetokyo.bof.bench.Benchmark.main(Benchmark.groovy:36)
Exception in thread "main" groovy.lang.MissingMethodException: No signature of method: java.lang.String.toInteger() is applicable for argument types: () values: []
        at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:55)
        at org.codehaus.groovy.vmplugin.v7.IndyInterface.unwrap(IndyInterface.java:356)
        at java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L1(MethodHandleImpl.java:1125)
        at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:685)
        at org.jggug.javaonetokyo.bof.bench.Benchmark.main(Benchmark.groovy:42)

My environment:

$ java -version
Picked up _JAVA_OPTIONS: -Dfile.encoding=utf-8 -Xms128m -Xmx1024m
java version "1.7.0_04-ea"
Java(TM) SE Runtime Environment (build 1.7.0_04-ea-b19)
Java HotSpot(TM) 64-Bit Server VM (build 23.0-b20, mixed mode)

Ok, I'll try to run the benchmark on other environments later. > blackdrag

@nobeans
Copy link
Author

nobeans commented Apr 11, 2012

"-Xbootclasspath/a:build/classes/main:libs/groovy-all.jar" seems wrong.
when I run a sample code with groovy1.8.6 and the above option, the MissingMethodException error also occurred.

@blackdrag
Copy link

the NPE comes from not finding the ressource META-INF/dgminfo which should be part of the jar. I assume your jar contains that file, so no idea why it doesn't look on the boot classpath for this.

@nobeans
Copy link
Author

nobeans commented Apr 12, 2012

The same benchmark works well on linux with java7u3(stable).

$ uname -a
Linux xxxx 2.6.32-25-generic #45-Ubuntu SMP Sat Oct 16 19:48:22 UTC 2010 i686 GNU/Linux

$ java -version
java version "1.7.0_03"
Java(TM) SE Runtime Environment (build 1.7.0_03-b04)
Java HotSpot(TM) Server VM (build 22.1-b02, mixed mode)

with indy:

$ env GROOVY_INDY=true ./gradlew clean bench -Dtrials=5
:clean
:compileJava UP-TO-DATE
:compileGroovy
:processResources
:classes
:benchmark
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  948876314
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  860028745
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  841997085
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  921306568
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  849809542

BUILD SUCCESSFUL

Total time: 1 mins 16.042 secs

without indy:

$ ./gradlew clean bench -Dtrials=5
:clean
:compileJava UP-TO-DATE
:compileGroovy
:processResources
:classes
:benchmark
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  114284947
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  104666545
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  106303189
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  104987396
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  110355638

BUILD SUCCESSFUL

Total time: 1 mins 8.742 secs

The unit is "nano seconds". The performance with indy option is about nine times slower than without indy option.

@glaforge
Copy link

Out of curiosity, do you have a u4 on Linux available too?
I'd be curious to see if the performance is as disastrous, or if that update improves the situation.

Basically, there are still areas where we can improve our usage of invoke dynamic.
But the big problem right now, IMHO, is that the JVM doesn't do its job yet properly well enough to optimize the usage of invoke dynamic :-(
So there area some benchmarks where we'll gain a lot, and others we'll get worse results, but we don't necessarily know if there's a way we can help the JVM do its job better or if we just have to wait for newer updates from the JVM :-(

@nobeans
Copy link
Author

nobeans commented Apr 12, 2012

Hmmm. I got a same result by jdk7u4_b19.

$ uname -a
Linux xxxx 2.6.32-25-generic #45-Ubuntu SMP Sat Oct 16 19:48:22 UTC 2010 i686 GNU/Linux

$ java -version
java version "1.7.0_04-ea"
Java(TM) SE Runtime Environment (build 1.7.0_04-ea-b19)
Java HotSpot(TM) Server VM (build 23.0-b20, mixed mode)

with indy:

$ env GROOVY_INDY=true ./gradlew clean bench -Dtrials=5
:clean
:compileJava UP-TO-DATE
:compileGroovy
:processResources
:classes
> Building > :benchmark
:benchmark
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  929356177
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  824207536
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  835715784
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  839375840
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  892661785

BUILD SUCCESSFUL

Total time: 1 mins 16.165 secs

without indy:

$ ./gradlew clean bench -Dtrials=5
:clean
:compileJava UP-TO-DATE
:compileGroovy
:processResources
:classes
:benchmark
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  107938108
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  113513512
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  106990819
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  107578011
src/main/resources/rbtree_map_input.csvを読み込んで赤黒木を構築した後にチェックする(put & get)  107505645

BUILD SUCCESSFUL

Total time: 1 mins 7.432 secs

@nobeans
Copy link
Author

nobeans commented Apr 12, 2012

Certainly, It's a difficult task because JVM itself isn't stable.
I expect @nahi who is an expert of indy for jruby could give you the advice about an optimization of indy ;-)

@nobeans
Copy link
Author

nobeans commented Apr 12, 2012

You can easyly run the benchmark as same as mine:

preparation:
$ git clone git://github.com/nobeans/javaone-tokyo-2012-jvm-bof.git
$ cd javaone-tokyo-2012-jvm-bof.git
$ git checkout groovy-2.0.0b-indy

with indy:
$ env GROOVY_INDY=true ./gradlew clean benchmark

without indy:
$ ./gradlew clean benchmark

@glaforge
Copy link

@nobeans thanks for those benchmark runs, and thanks for the exact instructions!

@blackdrag
Copy link

@nobeans, I tried that out and on my computer:
Linux xxxx 2.6.32-31-generic #61-Ubuntu SMP Fri Apr 8 18:25:51 UTC 2011 x86_64 GNU/Linux
java version "1.7.0_02"
Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
Java HotSpot(TM) 64-Bit Server VM (build 22.0-b10, mixed mode)

since the variation in that test is on my system about 30%, indy being enable or not makes no difference at all. In fact I would say the average for indy is the same, if not better. But it really depends. two runs of non indy test and you get two quite different averages too.

I would assume that file IO is dominating on my system for this test, thanks to that file#eachLine

@blackdrag
Copy link

ok, I take that with the IO back. I tried it with a different version and that one was even slower.

@blackdrag
Copy link

running with jdk7u3 (build 1.7.0_03-b04) the results look similar. For non indy I get values from 213-299 ms and for indy I get values from 153-196 ms, and the averages (10 tries) are at 245 (-32/+54) for normal Groovy and 180ms (-37/+16) for indy. And judging from the variation normal Groovy has a tendency to 213, while indy has a tendency to 196. That would make indy still 10% faster than normal Groovy of course.. All in all the values are on average better for indy now actually. Before the values did overlap more.

Anyway... indy being 9 times slower is something I cannot reproduce

@blackdrag
Copy link

One more interesting part... my fastest results are still only half the speed of yours, while my indy results are around 4.5 times faster.

@nobeans
Copy link
Author

nobeans commented Apr 15, 2012

I've caught the flu since Friday...

@glaforge
Copy link

No worries, take care!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment