November 3, 2012

Dart - the king of speed

The web as a platform is moving at an incredible pace right now. The modern web browsers are getting better in supporting the new HTML5 standards. Javascript runs 100 times faster now compared to 2007, according to Lars Bak the designer behind V8. Rich web applications are now developed as a single-page with most of the logic on the client. The gap between web applications and traditional native desktop application is getting smaller.

Chrome V8 performance from Google IO 2012 
I have a long experience in writing large-scale applications in Java using modular and object-oriented concepts on the Eclipse Rich-Client Platform. I have used the Eclipse Modeling Framework (EMF) to generate editors from domain models, and the Graphical Editing Framework (GEF) for adding graphical editing capabilities. I am spoiled with having lots of support from the platform.

Implementing similar applications on the web platform with Javascript seems like travelling back ten years in time. There are several popular frameworks that fix some of the really bad parts of Javascript and also add support for classes and components. But, you still have to write lots of boilerplate code to support things I am used to getting from the platform.

I am quite novice when it comes to web programming, but I do have some experience with the Google Web Toolkit (GWT). It has support for both EMF and GEF, and seems like a path for writing very rich and capable web applications. The drawback with GWT is that you are stuck with Java, which is lacking many of the more modern language features such as first-class support for functions. Also, there is a compile step to Javascript which makes edit-and-continue debugging hard to achieve.

Using GWT feels like driving an old reliable Volvo. It is safe and you don't have to worry crashing . But suddenly a new fresh-looking sports-car is passing you on the street. It is looking better, has nicer features and seems faster, but maybe not as crash-safe as a Volvo yet... In this analogy the faster car is the new Dart language that Google has been working hard on for more than a year. Dart is designed from ground up to support writing large, structured and performant web applications. The Dart VM engine it is already outperforming V8 in several key benchmarks. The goal according to Lars Bak's talk at Strange Loop is to make it at least twice as fast as V8. Maybe "V16" would be an appropriate name...

I think Dart may be the platform of choice for many developers with my background. Dart is not just a new language. It has great tooling with an Eclipse-based editor, new frameworks and a package manager "pub". The VM will initially only be available in Chrome, but Dart code can be compiled to Javascript, thus supporting all modern browsers.

Lars Bak said "speed is king!". If he can deliver that, I believe Dart has a big chance of being more than just a niche language.

April 2, 2012

EclipseCon 2012

EclipseCon2012 Cover

This year's EclipseCon was especially exciting because my colleague Fredrik and I had a talk accepted and was one of a few highlighted sessions.

Our talk was about sharing our experiences of migrating one of FindOut's tools to the new Rich Client Platform "RCP 2.0" in Eclipse 4.2:



Here are the highlights from the conference:

Monday:

The conference started out with an excellent tutorial on writing rich client applications with Eclipse RCP 4.x by Kai Toedter. He also showed that the default SWT rendering engine in the platform can be replaced with Swing. He used the Napkin theme for his contacts demo. Very impressive!


Tuesday:

Tom Schindl explained the new application platform and showed how to easily pool resources and a locale support service that he connected to google translate. The audience was asked for a language to translate to, and without restarting the application "Hello World" was switched to "Hallo Verden" (Norwegian). Impressive!

Brian de Alwis showed how to style your 4.x application with CSS. He also demoed the nifty CSS Spy and editors. For us who had little knowledge of CSS this tool came in real handy.

Alexander Nyßen gave a comprehensive overview and history of GEF. He also explained GEF4 and the main priorities to introduce there. We were especially glad that one of the bullets was to migrate GEF to use the new 4.x application platform.

Wednesday:

e4 compatibility layer sketch
Figuring out the compat layer
Tom Schindl talked about e(fx)clipse which is a distribution of Eclipse for creating JavaFX applications. He also showed that the default SWT rendering engine in can be replaced with JavaFX.

After lunch it was time for us to present.  We were happy to see that we had about 60-70 attendees in the room. The presentation and demo went very well and we had a very good discussion with the audience during the Q/A.
Eclipse 4 BOF signup
In the evening we attended the e4 BOF which was well attended with all the key people from development and a number of users. One interesting topic was how the solve the problem of having multiple dependency injection frameworks. One example is that Xtext uses Guice. It was also noted that 4.2 is lacking a documented API, something that will be addressed in 4.3. Many of the common UI components such as the Properties view, the Project Explorer and the Preference dialog need to be migrated to the new platform services.




Thursday:

Eclipse 4 meets CDO - inspiring demo of what you can do with the modeled application. Since the application model is implemented using EMF, CDO can be used to share it between multiple users. Think instant content sharing and collaboration using the application model.

Wrap-up session
In the closing session it was revealed that the conference had 650 attendees with 360 of them first-timers. 36 countries and 41 US states were represented. There were 2972 complaints on the WiFi according to Mike Milinkovic. All of this was washed down with almost 7000 beers.

One valuable thing for us was meeting and mingling with everyone including other swedes from companies such as Ericsson, Sandvik, IAR and Oracle...

It was also great to meet the e4 team face to face. We would especially like to thank Remy Suen for fixing a bug that we ran into when migrating our application.

Finally, a special thanks to the Eclipse Foundation for yet another great Eclipse conference!

References


December 6, 2011

Eclipse 4.x presentation and Eclipsecon 2012




I presented an overview of the new Eclipse 4.x platform at the Eclipse 10 years celebration in Stockholm together with my colleague Fredrik Attebrant. We had a big crowd that was interested in the new possibilities, such as CSS styling and dependency injection. One of the key points we made was that your existing 3.x applications can run unmodified using the compatibility layer. That way your old looking application can get a total makeover using the new styling possibilities with a minimal effort.

Afterwards we got to enjoy the cake sponsored by our company.



For those of you that missed the talk there is an opportunity to listen to us at Eclipsecon 2012.
See you there!





October 18, 2011

Scaling up (enhanced)

The results of trying to scale up in my previous post was so disappointing that I asked Martin Odersky, the creator of Scala, for some advice. He helped me get in touch with the author of Scala's parallel collections, Aleksandar Prokopec. Here is his feedback:
  1. Always use the scala.testing.Benchmark class to measure performance
  2. Always use the server VM. Benchmark results will in most cases be entirely different.
  3. There are no parallel lists - when calling .par on a list, it gets converted to the standard immutable parallel collection, which is ParVector. Transformer methods (such as filter and map) process items in parallel, but construct the final parallel vector sequentially - until vector concatenation is built into the standard library, the construction of the parallel vector will not be parallelized. We are looking into adding concats. In the meantime, I suggest using parallel arrays and comparing them against regular arrays in terms of performance.
  4. Every invocation of a parallel method requires some sync, so you might want to keep the number of invocations to a minimum. This is particularly the case with transformer methods which produce intermediate collections - thus possibly invoking gc cycles.
... and the modified version of the example:
object util {
  val studentCount = 1000000
}

case class Student(gradYear: Int, score: Double)

object StudentExample extends testing.Benchmark {
  val students = (for (i <- 1 to util.studentCount) 
    yield new Student(2010 + (i % 2), math.random)).toArray

  def run() {
    val gradYear = 2011
    students.filter(_.gradYear == gradYear).map(_.score).fold(0.0d)(math.max)
  }
}

object StudentExamplePar extends testing.Benchmark {
  val students = (for (i <- 1 to util.studentCount)
    yield new Student(2010 + (i % 2), math.random)).toArray.par

  def run() {
    val gradYear = 2011
    students.filter(_.gradYear == gradYear).map(_.score).fold(0.0d)(math.max)
  }
}

object StudentExampleImp extends testing.Benchmark {
  val students = (for (i <- 1 to util.studentCount)
    yield new Student(2010 + (i % 2), math.random)).toArray

  def run() {
    val gradYear = 2011
    var maxscore = 0.0d
    for (student <- students)
      if (student.gradYear == gradYear)
        maxscore = math.max(maxscore, student.score)
  }
}
... and the results on my dual-core MacBook Pro:
$ java -server -cp /scala-2.9.1.final/lib/scala-library.jar:. StudentExample 10
StudentExample$ 273 38 35 40 36 36 36 36 35 39

$ java -server -cp /scala-2.9.1.final/lib/scala-library.jar:. StudentExamplePar 10
StudentExamplePar$ 495 32 31 31 30 30 30 32 30 31
... and the results on my quad-core iMac:
$ java -server -cp /scala-2.9.1.final/lib/scala-library.jar:. StudentExample 10
StudentExample$ 154 18 17 17 17 17 17 17 17 17

$ java -server -cp /scala-2.9.1.final/lib/scala-library.jar:. StudentExamplePar 10
StudentExamplePar$ 222 10 10 10 9 10 10 10 10 10
A performance gain can now be seen, but both Aleksandar and I agreed that it wasn't the expected speedup. As a reference I also ran the imperative example, which still was by far the most efficient. The results on the dual-core was:
$ java -server -cp /scala-2.9.1.final/lib/scala-library.jar:. StudentExampleImp 10
StudentExampleImp$ 24 7 13 12 10 10 11 11 13 13

October 10, 2011

Scaling up

Photo by chaoticzee
A trend in modern programming languages is to simplify parallel computation so that the increasing number of cores in processors can be utilized. The days where the clock-speed increased according to Moore's law are over, so a single-threaded code does not benefit much from newer hardware anymore. This is one of the major reasons why functional languages are enjoying a renaissance, since functions with no mutable state can be parallelized much easier. In a functional language you declare what to do, but not how to do it.
Developing concurrent software with Java has always been hard to get right for the average programmer. With Java 7 the fork/join framework is introduced, but we'll have to wait for Java 8 to get lambda expressions (closures) in Java. The technical keynote at JavaOne 2011 nicely summarizes these features using a simple example of calculating the best graduate score among students. The functional implementation of the task is shown to be much simpler than using the fork/join framework. The nice thing is that it's implicitly relying on the collections framework to do the parallelization of the higher-order functions on the list.

One of the more popular languages that was built from ground up to be scalable is Scala. For a good introduction, watch the presentation given by the language creator himself: Martin Odersky at Scala days 2011. In the presentation he introduces the new parallel collections and shows how to easily utilize them in a small example.
Scala has been around for almost ten years and has recently gained a lot of interest. The Scala IDE is a nice integration with Eclipse supporting content assist, refactor and debug support, and since Scala runs on top of the JDK it can be nicely mixed with Java components.
This means you can start implementing the time critical computations in Scala now rather than to wait for Java 8.

Let's create an example similar to the one from the JavaOne keynote and see how it would look like in Scala:
package com.example
import scala.collection.parallel.immutable.ParSeq

object StudentExample {
  // The student class
  class Student(val gradYear: Int) {
    // The score is calculated randomly
    def score: Double = {
      var sum = 0.0d
      for (i <- 1 to 100)
        sum += Math.random / 100
      return sum
    }
  }
In trying to benefit anything from parallelization I had to do introduce some non-trivial calculation when getting the student score, like summing up 100 random scores.

This is how an imperative implementation of the maximum score would look like:
def maxScoreImperative(students: List[Student], gradYear: Int): Double = {
    var max = 0.0d
    for (student <- students)
      if (student.gradYear == gradYear)
        max = Math.max(max, student.score)
    return max
  }
This is easily understood by a Java programmer, but the functional implementation may be a bit harder to grasp depending on your background:
def maxScore(students: List[Student], gradYear: Int): Double =
    students.filter(_.gradYear == gradYear).map(_.score).fold(0.0d)(Math.max)
The important thing to note is that three higher-order functions filter, map and fold are applied on the student list to achieve the same result.
The recent ParSec class can be used instead of the List to get implicit parallelization of List functions:
def maxScorePar(students: ParSeq[Student], gradYear: Int): Double =
    students.filter(_.gradYear == gradYear).map(_.score).fold(0.0d)(Math.max)
Now on to my highly unscientific test of the three different implementations of the maxScore function:
def main(args: Array[String]) {
    // Create a million students, where every other graduates 2011
    var students = List[Student]()
    for (i <- 1 to 1000000) {
      val gradYear = 2010 + (i % 2)
      students = new Student(gradYear) :: students
    }
    // This is the parallel version of the list
    val studentsPar = students.par
    // Measure the time ten times
    var measuredTimes = List[Long]()
    for (i <- 1 to 10) {
      val tick = System.currentTimeMillis()
      val max = maxScoreImperative(students, 2011)
      val tock = System.currentTimeMillis()
      measuredTimes = (tock - tick) :: measuredTimes
    }
    // Skip first result due to JVM warmup
    measuredTimes = measuredTimes.tail;

    println("Average time: " + math.round(measuredTimes.sum.toDouble / measuredTimes.length) + "ms")
  }
}
Similarly, the maxScore and the maxScorePar implementations where measured.

Using Scala 2.9.1 the result on my dual-core MacBook Pro was:
  • Average time imperative: 2.4s
  • Average time functional: 2.8s
  • Average time functional parallel: 3.9s
Trying on a new quad-core iMac gave the following results:
  • Average time imperative: 1.2s
  • Average time functional: 1.5s
  • Average time functional parallel: 10.0s (!)
The imperative was a bit faster than the functional, which wasn't so surprising, but I was expecting much better results from the parallel list implementation.  The only thing that scaled up using this example was the execution time! The Scala parallel collections was introduced only a year ago in version 2.8 so I guess there is room for improvement.

Updated: For some comments and better results see the Scaling up (enhanced) post...

May 19, 2011

Writing games using GWT and Eclipse


Finally Angry Birds is available on the web platform! I was not so impressed by the news from Google I/O until I heard that the implementation was done using Google Web Toolkit (GWT), a technology that has caught my interest lately. The good thing with GWT is that I don't need to hack Javascript and HTML5, but rather continue using Java with my favorite editor/debugger: Eclipse.

The Google I/O session Kick-Ass Game Programming with Google Web Toolkit explains further that Angry Birds is using the Box2D physics engine, which according to the presenter's guess 90% of all iPhone games are using. The Google guys took the Java version of Box2D, ported it and optimized it for GWT (in 30 mins!), and wrote a cross-platform game abstraction library, called ForPlay.

The idea is really compelling; instead of writing and maintaining several codebases of your game for different platforms, a ForPlay game can be run on the web platform (HTML5), as a Java program or even using Flash. Thrilled to try out this new platform, I wrote my first "game", well ... not really a game, but I thought it would be interesting to see how our company logo behaves in free fall. The result is on http://findoutlogo.appspot.com. It is based on the "Hello Game" demo you get when checking out the ForPlay source.

The FindOut Logo game (hint: click to drop a new logo or click and drag to "throw it")
I am very glad to see that you can leverage the existing ecosystem of components, even when doing game programming, and that GWT seems to be a great technology for managing code sharing when dealing with many target platforms.

March 27, 2011

Eclipsecon 2011

I really enjoy going to Eclipsecon even though for us Europeans the trip over takes forever and you have to fight jet lag due to the huge time difference.

This year I found many talks interesting and especially a couple of them touched on the same subject, namely how to design large-scale applications.

The talk Stop the Architecture Erosion of Eclipse And Open Source Projects explained the usual scenario: when a small application grows the architecture starts decaying, leading up to a non-maintainable mess of spaghetti code. As an example the project Findbugs was analyzed from the start, and with each version it was shown that new tangles (circular dependencies) had been introduced and was never fixed. There are several programs (both commercial and open-source) that can reveal these problems and even suggest improvements.




CDO3D

A really cool way of visualizing the run-time behavior of a program was shown in the CDO3D talk. CDO has a really good architecture that can handle large distributed EMF models. The object dependencies were visualized in 3D so that you could see when the client objects were committed to the server and how a second client was notified and populated with the new objects.

One of the most important goals in having a sound architecture is to avoiding tight coupling. In the talk Introduction to OSGi, Peter Kriens explained how OSGi added modules (bundles) to Java so that internal packages can be hidden. He explained the well proven pattern of communicating through interfaces so that you avoid a direct coupling between a consumer and its provider.
Avoiding direct coupling by communicating through an interface
The below diagram from his presentation summarizes nicely the four different patterns of communicating between a consumer and a provider. Peter Kriens explained that OSGi services, or (micro)Services as he likes to call them, can handle all four cases.

Patterns communicating between consumer and provider
OSGi has been getting a lot of critique for being complicated. With the introduction of declarative services and the tool support in Eclipse 3.x, it is now much easier to utilize dynamic services than trying to implement a ServiceTracker correctly. With Eclipse 4.x, dependency injection is a key theme in the architecture and OSGi services can easily be injected in parts (views or editors).

Sven Efftinge's talk on Dependency Injection reiterated the importance of not having static dependencies to enable unit testing with "test doubles" (stub-, mock-, fake- or dummy objects). He shared his experience on using the Google Guice (pronounced "Juice") dependency injection framework in the Xtext project. I also found out that there is a nice extension to Guice called Peaberry that integrates Guice nicely within an OSGi application developed with Eclipse. With the help of Peaberry you can inject OSGi services in your classes. It also provides an integration with the Eclipse extension framework so that views, commands, etc. can utilize Guice injections. During late hours I played around with Guice and Peaberry and it was actually very simple to get it working.

Another really cool technology from Google is GWT. In the GWT App start to finish, I learned how easy it is to write browser-based rich internet applications without hacking Javascript. Being able to use EMF in GWT as shown by Ed Merks, makes it even more compelling since you can store the state on the client in an EMF generated model implementation.

This was just a few of the highlights this year and with lots of inspiration and new energy I am now back home again quickly adjusting to summertime.