About Me

My photo
Author of Groovy modules: GBench, GProf, Co-author of a Java book パーフェクトJava, Game Developer at GREE

Friday, November 8, 2013

Build OpenJFX 8 on OS X 10.9 Mavericks

1. Clone OpenJFX 8.
$ openjfx% hg clone http://hg.openjdk.java.net/openjfx/8/graphics/rt
$ openjfx% cd rt
2. Checkout a tag for your JDK.
$ openjfx/rt% java -version  2>&1 | grep "build 1.8"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b111)
$ openjfx/rt% hg checkout 8.0-b111
3. Set properties for Mavericks.
$ openjfx/rt% cat gradle.properties
MACOSX_MIN_VERSION=10.9
MACOSX_JDK_FRAMEWORK=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/JavaVM.framework
4. Build jfxrt.jar.
$ openjfx/rt% gradle jfxrtMac
5. (If you want to use OpenJFX as default) Replace the bundled jar with the jar you built.
$ openjfx/rt% sudo mv $JAVA_HOME/jre/lib/ext/jfxrt.jar $JAVA_HOME/jre/lib/ext/jfxrt.jar.orig
$ openjfx/rt% sudo cp build/mac-sdk/rt/lib/ext/jfxrt.jar $JAVA_HOME/jre/lib/ext/jfxrt.jar
That's it. Enjoy the open source JavaFX ;)

Saturday, September 14, 2013

GProf 0.3.0 is out!

Today I released the Groovy profiler, GProf 0.3.0. GProf is a profiling module for Groovy which is developed in GPerfUtils project at http://gperfutils.org. The release includes the GNU profiler compatible call graph report and many improvements. You can read all the changes at https://code.google.com/p/gprof/wiki/ReleaseNotes030).

The release already has been available on the Maven Central repository and it means that now you can install GProf by the following one line:

@Grab('org.gperfutils:gprof:0.3.0-groovy-2.1') // v0.3.0 for Groovy 2.1

Here is a demo:

// slow !!
def fib(n) {
    if (n < 2) {
        n
    } else {
        fib(n - 1) + fib(n - 2)
    }
}

profile {
    fib(20)
}.prettyPrint()
and the output will be like this:
Flat:

 %    cumulative   self            self     total    self    total   self    total
time   seconds    seconds  calls  ms/call  ms/call  min ms  min ms  max ms  max ms  name
54.3        0.29     0.29      2   145.86   267.78   38.14   58.56  253.57  477.00  demo.fib
30.4        0.45     0.16  21890     0.00     0.00    0.00    0.00    0.80    0.80  java.lang.Integer.minus
15.0        0.53     0.08  10945     0.00     0.00    0.00    0.00    0.83    0.83  java.lang.Integer.plus
 0.1        0.53     0.00      1     1.05   537.10    1.05  537.10    1.05  537.10  demo$_run_closure1.fib
 0.0        0.53     0.00      1     0.13   537.23    0.13  537.23    0.13  537.23  demo$_run_closure1.doCall

Call graph:

index  % time  self  children  calls        name
               0.00      0.53          1/1      
[1]     100.0  0.00      0.53            1  demo$_run_closure1.doCall [1]
               0.00      0.53          1/1      demo$_run_closure1.fib [2]
-----------------------------------------------------------------------------
               0.00      0.53          1/1      demo$_run_closure1.doCall [1]
[2]      99.9  0.00      0.53            1  demo$_run_closure1.fib [2]
               0.29      0.24          2/2      demo.fib [3]
               0.00      0.00      2/21890      java.lang.Integer.minus [4]
               0.00      0.00      1/10945      java.lang.Integer.plus [5]
-----------------------------------------------------------------------------
               0.29      0.24          2/2      demo$_run_closure1.fib [2]
[3]      99.6  0.29      0.24      2+21888  demo.fib [3]
               0.16      0.00  21888/21890      java.lang.Integer.minus [4]
               0.08      0.00  10944/10945      java.lang.Integer.plus [5]
-----------------------------------------------------------------------------
               0.00      0.00      2/21890      demo$_run_closure1.fib [2]
               0.16      0.00  21888/21890      demo.fib [3]
[4]      30.4  0.16      0.00        21890  java.lang.Integer.minus [4]
-----------------------------------------------------------------------------
               0.00      0.00      1/10945      demo$_run_closure1.fib [2]
               0.08      0.00  10944/10945      demo.fib [3]
[5]      15.0  0.08      0.00        10945  java.lang.Integer.plus [5]
-----------------------------------------------------------------------------

I welcome any requests or feedback.

Thursday, May 2, 2013

GBench Goodness: Compare the performance of different versions of Groovy using GVM

As I announced in my last post, "GProf Goodness: Profile a fork/join program written in GPars", I started Goodness series for GPerfUtils (GBench and GProf). And now it's the turn of GBench.

GBench is the benchmarking module of Groovy. It allow you to accurately and easily benchmark a Groovy program. GVM is a tool for managing parallel versions of Groovy and other Groovy-related tools. By combining the tools, you can easily compare the performance of different versions of Groovy. This is a script to compare the performance of Fibonacci number calculation among v1.7.11, v1.8.9, v2.0.8, and v2.1.3 (you have to install GVM first if you haven't done it yet).

#!/bin/bash
source ~/.gvm/bin/gvm-init.sh
 
versions=(1.7.11 1.8.9 2.0.8 2.1.3)
 
for version in ${versions[*]}
do
  echo -n "Install groovy v${version}"
  gvm install groovy $version
done
 
echo "Okie-dokie, let's benchmark them!"
 
for version in ${versions[*]}
do
  gvm use groovy $version > /dev/null &&
  running_version=$(groovy -v | cut -d' ' -f 3) &&
  major_version=$(echo $running_version | cut -d'.' -f1,2) &&

  groovy -e "
    @Grab('org.gperfutils:gbench:0.4.2-groovy-${major_version}')
    def fib(int n) {
        (n < 2) ? 1 : fib(n - 1) + fib(n - 2)
    }
    // benchmark() extension is supported only in Groovy 2.0 or later versions.
    new groovyx.gbench.BenchmarkBuilder().run(quiet:true, measureCpuTime:false) {
        'v${major_version}' { fib(20) }
    }.prettyPrint()
  " &&

  sleep 1
done

[NOTE] If you face "gvm: command not found" error, try the following approach until my pull request for fixing the issue is merged to GVM.

  1. Download gvm-include.sh from my Gists
  2. Make gvm-include.sh executable by "chmod +x gvm-include.sh"
  3. Replace "source ~/.gvm/bin/gvm-include.sh" in the benchmark script to "source /path/to/gvm-include.sh"

This is the results of the script in my environment. This shows us that the performance of numeric operations were highly improved in v1.8 at least:

v1.7  870633
v1.8  535506
v2.0  507253
v2.1  489244

Please send me pull requests at the Github page or any issues, requests to the Issue page to improve GBench.

Friday, April 26, 2013

GProf Goodness: Profile a fork/join program written in GPars

I just started to write Goodness series for GPerfUtils (GBench and GProf) like the great Groovy Goodness series by Hubert Klein. And this is the first post of GProf Goodness.

First of all, I should explain about GProf. GProf is the profiling module for Groovy. The purpose of the module is agile profiling. It means that you can profile Groovy program whenever and wherever you want. You don't have to go through lengthy tiresome procedure.

OK, let's back to the topic. GProf supports multi-threaded programs. The following example is to profile a fork/join example of GPars from the GPars user guide.

// prof.groovy
@Grab('org.gperfutils:gprof:0.2.0')

import static groovyx.gpars.GParsPool.runForkJoin
import static groovyx.gpars.GParsPool.withPool

profile {
  withPool(2) { pool ->
      println """Number of files: ${
          runForkJoin(new File("./src")) {file ->
              long count = 0
              file.eachFile {
                  if (it.isDirectory()) {
                      forkOffChild(it)       //fork a child task
                  } else {
                      count++
                  }
              }
              return count + (childrenResults.sum(0))
              //use results of children tasks to calculate and store own result
          }
      }"""
  }
}.prettyPrint()
The results will be like this:
Number of files: 2145
%      calls  total ms  ms/call  min ms  max ms  method                   class
29.47      1    342.87   342.87  342.87  342.87  runForkJoin              groovyx.gpars.forkjoin.ForkJoinUtils
14.87   2403    173.04     0.07    0.05    4.09  doCall                   prof$_run_closure1_closure2_closure3_closure4
 9.41   2403    109.51     0.05    0.03    4.06  isDirectory              java.io.File
 9.16    259    106.61     0.41    0.11    9.08  eachFile                 java.io.File
 8.83    259    102.72     0.40    0.10   21.59  doCall                   prof$_run_closure1_closure2_closure3
 4.80   2145     55.81     0.03    0.02    2.80  next                     java.lang.Long
 3.61      1     42.00    42.00   42.00   42.00  use                      groovyx.gpars.GParsPool
 2.90      1     33.73    33.73   33.73   33.73  call                     prof$_run_closure1_closure2
 2.53      1     29.39    29.39   29.39   29.39  withExistingPool         groovyx.gpars.GParsPool
 2.46    258     28.68     0.11    0.04   14.86  forkOffChild             prof$_run_closure1_closure2_closure3
 1.92      1     22.34    22.34   22.34   22.34  createPool               groovyx.gpars.GParsPool
 1.56      2     18.12     9.06    4.99   13.13  withPool                 groovyx.gpars.GParsPool
 1.43    258     16.66     0.06    0.04    4.32  forkOffChild             prof$_run_closure1_closure2_closure3_closure4
 1.40    409     16.24     0.04    0.02    0.93  plus                     java.lang.Long
 1.28    258     14.89     0.06    0.04    0.84  forkOffChild             groovyx.gpars.forkjoin.FJWorker
 0.94      1     10.93    10.93   10.93   10.93  println                  prof$_run_closure1_closure2
 0.80    108      9.27     0.09    0.04    0.71  sum                      java.util.Arrays$ArrayList
 0.75      1      8.67     8.67    8.67    8.67  runForkJoin              groovyx.gpars.GParsPool
 0.64    151      7.48     0.05    0.02    1.86  sum                      java.util.Collections$EmptyList
 0.36      1      4.18     4.18    4.18    4.18  asType                   groovyx.gpars.GParsPool$_createDefaultUncaughtExceptionHandler_closure4
 0.25    108      2.85     0.03    0.02    0.05  plus                     java.lang.Integer
 0.20      1      2.28     2.28    2.28    2.28  getAt                    [Ljava.lang.String;
 0.10      1      1.13     1.13    1.13    1.13  ctor                     jsr166y.ForkJoinPool
 0.06      2      0.68     0.34    0.03    0.66  size                     [Ljava.lang.Object;
 0.05      1      0.61     0.61    0.61    0.61  isCase                   groovy.lang.IntRange
 0.05      1      0.61     0.61    0.61    0.61  minus                    java.lang.Integer
 0.05      1      0.61     0.61    0.61    0.61  retrieveCurrentPool      groovyx.gpars.GParsPool
 0.04      1      0.44     0.44    0.44    0.44  toInteger                java.lang.String
 0.03      1      0.32     0.32    0.32    0.32  retrieveDefaultPoolSize  groovyx.gpars.util.PoolUtils
 0.02      2      0.21     0.10    0.07    0.14  doCall                   groovyx.gpars.GParsPool$_withExistingPool_closure1
 0.01      1      0.11     0.11    0.11    0.11  leftShift                groovyx.gpars.ThreadLocalPools
 0.01      1      0.11     0.11    0.11    0.11  shutdown                 jsr166y.ForkJoinPool
 0.01      1      0.09     0.09    0.09    0.09  awaitTermination         jsr166y.ForkJoinPool
 0.01      2      0.09     0.04    0.04    0.05  getAt                    [Ljava.lang.Object;
 0.01      1      0.07     0.07    0.07    0.07  ctor                     groovyx.gpars.ThreadLocalPools
 0.01      1      0.07     0.07    0.07    0.07  pop                      groovyx.gpars.ThreadLocalPools
 0.00      1      0.05     0.05    0.05    0.05  ctor                     java.io.File
 0.00      1      0.04     0.04    0.04    0.04  asType                   prof$_run_closure1_closure2_closure3

Also, you can choose threads that you are interested in by includeThreads and excludesThreads options. The following change is to profile only worker threads which GPars gives a name starting with "ForkJoinPool". The options allow "*" and "?" wildcards. You don't have to specify the names of all the threads.

// profile {
profile(includeThreads: [ "ForkJoinPool*" ]) {
    ...
}.prettyPrint()
The results will be changed like this:
Number of files: 2145
%      calls  total ms  ms/call  min ms  max ms  method        class
27.42   2403    268.07     0.11    0.07    4.12  doCall        prof$_run_closure1_closure2_closure3_closure4
21.63   2403    211.49     0.09    0.04   52.46  isDirectory   java.io.File
14.20   2145    138.80     0.06    0.03   51.11  next          java.lang.Long
13.61    259    133.05     0.51    0.12   13.41  eachFile      java.io.File
 9.40    259     91.94     0.35    0.14   12.16  doCall        prof$_run_closure1_closure2_closure3
 3.54    258     34.61     0.13    0.05   15.03  forkOffChild  prof$_run_closure1_closure2_closure3
 2.58    409     25.22     0.06    0.03    4.28  plus          java.lang.Long
 1.98    258     19.39     0.08    0.05    1.20  forkOffChild  groovyx.gpars.forkjoin.FJWorker
 1.95    258     19.06     0.07    0.05    0.52  forkOffChild  prof$_run_closure1_closure2_closure3_closure4
 1.66    108     16.18     0.15    0.06    3.94  sum           java.util.Arrays$ArrayList
 1.15    108     11.20     0.10    0.03    6.34  plus          java.lang.Integer
 0.90    151      8.81     0.06    0.03    1.97  sum           java.util.Collections$EmptyList

Please send me pull requests at the Github page or any issues, requests to the Issue page to improve GProf.

Saturday, April 20, 2013

This is the logo for GProf and GBench!!

I just drew the logo for GPerfUtils project that has GProf and GBench. I am not a good artist but I personally like the logo that is based on the Groovy Duke. How about you?
And this is the sketch.

Sunday, April 14, 2013

GProf 0.2.0 is out!

Today I released GProf 0.2.0! GProf is a profiling module for Groovy which is developed in GPerfUtils project at http://gperfutils.org. GBench which is a benchmarking module for Groovy is also a subproject of GPerfUtils. The release already has been available on the Maven Central repository and it means that now you can install GProf by the following one line:
@Grab('org.gperfutils:gprof:0.2.0')
The release includes big enhancements and important bug fixes. The changes are as follows (you can read it also at https://raw.github.com/gperfutils/gprof/master/NEWS):
Support multi-threaded applications

Support Grape

Add includeMethods and excludeMethods options that filter by the name of packages,
classes and methods:

    It supports the following wildcards:

        | * | zero or more characters |
        | ? | exactly one character   |

    The following example profile only methods which are of "java.*" or "groovy.*"
    package but are not constructors:

        profile(
            includeMethods: [ "java.*", "groovy.*" ],
            excludeMethods: [ "*.ctor" ]) {
            // code to be profiled
        }

Add includeThreads and excludeThreads options that filter by the name of threads:

    It supports the following wildcards:

        | * | zero or more characters |
        | ? | exactly one character   |

    The following example profile only methods which are called in the "thread-*"
    thread but not in "thread-2" or "thread-3":

        profile(
            includeThreads: [ "thread-*" ],
            excludeThreads: [ "thread-2", "thread-3" ]) {
            // code to be profiled
        }

Bug fixes:

- #3: GProf fails to profile a multi-threaded application
- #4: Contains the time of children if the depth is more than two
- #6: There are classes that are not profiled
Enjoy ;)

Wednesday, April 3, 2013

GProf was just born!

GProf a.k.a. Groovy gprof was just born Yesterday [https://code.google.com/p/gprof/]. GProf is a profiler for Groovy [http://groovy.codehaus.org/]. It allows you to determine which parts of a program are taking most of the execution time like GNU gprof does for C, C++.

For example, in the following code, GProf shows you that YourApp has two slow operation; one is a task that is short but repeated many times and another is a long task.

class YourApp {
    void start() {
        def foo = new Foo()
        for (int i = 0; i < 100; i++) {
            foo.doShortTask()
        }
        def bar = new Bar()
        bar.doLongTask()
    }
}

class Bar {
    void doLongTask() {
        for (int i = 0; i < 1000000; i++);
    }
}

class Foo {
    void doShortTask() {
        for (int i = 0; i < 10000; i++);
    }
}

profile {  // or new gprof.Profiler().run {
    new YourApp().start()
}.prettyPrint()

/* stdout
%      calls  total ms  ms/call  min ms  max ms  method       class
47.59      1     54.33    54.33   54.33   54.33  doLongTask   Bar
40.05    100     45.72     0.46    0.29    2.09  doShortTask  Foo
11.92      1     13.61    13.61   13.61   13.61  start        YourApp
 0.18      1      0.21     0.21    0.21    0.21  ctor         YourApp
 0.13      1      0.14     0.14    0.14    0.14  ctor         Bar
 0.13      1      0.14     0.14    0.14    0.14  ctor         Foo
*/
Please try GProf and send me your feecback. Enjoy!

Monday, March 25, 2013

GBench 0.4.2 released!

Today I released GBench 0.4.2, the benchmarking module of Groovy http://groovy.codehaus.org/. The release includes new system properties and fixes for providing more exact benchmark. Please check the release notes https://code.google.com/p/gbench/wiki/ReleaseNotes042 or visit the project site https://code.google.com/p/gbench/ for more info.

And now I started developing GBench 0.5.0. If you have requests or anything for this module, please send me a message or add a new issue to https://code.google.com/p/gbench/issues/list. Enjoy!

Saturday, March 16, 2013

GBench tutorial is now available!

For open source projects, one of the most important is without any doubt documentation. For example, Groovy project declared that they will make efforts to improve their documents few days ago: http://groovy.329449.n5.nabble.com/ANN-Documentation-effort-and-site-redesign-td5712875.html

Therefore, I also wrote a tutorial for GBench, the benchmarking module for Groovy: https://code.google.com/p/gbench/wiki/BenchmarkBuilderTutorial

It is a bit short but I hope this document helps your Groovy life as much as possible :)

Friday, March 8, 2013

GBench 0.4.1 released!

Today I released GBench 0.4.1, the benchmarking module of Groovy. The release includes an important bug fix for Invokedynamic. Please visit the GBench project site https://code.google.com/p/gbench/ for more info.