Feeds:
Posts
Comments

Posts Tagged ‘Groovy and Grails’

Well, I’m about to start development of a social application (Squirrel2 project) and I have to decide on what technology stack I’m going to use. This is a very important decision: making a wrong technology choice can easily result in project failure.

Here is a good research on the current technology stack of well-known social applications. Looks a bit intimidating, right? 🙂

Do I really need all this software? I don’t think so.

All new social applications face two major risk at the beginning:

  • Their development may be not complete at all. Most new social applications (with some exceptions like Google+) are developed either by individuals or small teams with very modest financing. In both cases resources are very limited and there may be just not enough time or money to complete development. This is very true in case of Squirrel2 – I have just around 500 hours for the whole development accordingly to my one year challenge.
  • Even if the initial development has been completed, the application may not get enough traction with its potential users. This happens more often than not. Therefore developers should bring a first version to production as soon as possible so that to verify its viability before too much money or effort is spent. This implies minimum of the initial development as well

So the bottom line is: the initial technology stack should be such so that to allow launching the first version of the application as soon as possible and with as less investment and development as possible.

Notably, initial versions of many successful social applications were built using technologies that are more known for rather rapid development then scalability or high performance:

  • The initial version of Twitter was built in Ruby on Rails.
  • The initial version of Facebook was built on PHP.

And what about scalability, ability to serve millions of concurrent users? I wish I had that problem 🙂 Those issues will be dealt with when and if it becomes necessary.

Squirrel2 technology stack must satisfy following requirements:

  • Main development environment/main technology should be optimized for quick development
  • At the same time it should have a clear transition path to more scalable solution
  • Technology stack must minimize amount of new development; the more ready made solutions I can use instead of doing my own development, the better. I will make exception for technologies that I’m specifically interested to learn, though
  • Technologies that I already know are preferable whenever feasible; I don’t have much time for learning given that the whole Squirrel2 development budget is 500 hours
  • Naturally, the technology stack should be suitable for development of web applications

I have been thinking of the technology stack for some time. Here is what I decided to use.

Main technology

Since my main competence as a software developer is in Java, I could choose that language as the main technology. However it would be somewhat boring… I want to learn new things, remember?

So after some research I have decided to use Grails.

A primary reason for this is that it is a rapid development technology. Yeah, I know it was inspired by Ruby on Rails, so should I have used RoR?

RoR is very good technology. The reasons why I decided on Grails and not on RoR are following:

  • I just happen to like Groovy (the language used by Grails). I think it yields in a very elegant and easy-to-understand code which I consider very important qualities. Absence of those qualities is the reason why e.g. I did not select Scala and Lift which I evaluated as well; to me Scala code is just somewhat cryptic and difficult to read.
  • Groovy produces quite compact code, about twice shorter than corresponding Java code. This is also a very important advantage in my opinion.
  • Groovy++ and Java (ability to mix Groovy and Java, to be precise) offer a clean and easy gradual path to future performance improvements in case I would need improve it. RoR does not offer a similar path as far as I know.
  • Ability to mix Groovy and Java allows leveraging a huge collection of high quality open source software that Java accumulated over time (remember, my goal is to minimize amount of development).

Grails comes with a lot of plugins that provide functionalities I hope to leverage. Grails community is vibrant. In short, Grails is “what the doctor prescribed” 🙂 Decided: my choice is Grails.

Database

Grails is mostly used with relational databases. I could use e.g. MySQL which have worked well for me in my previous projects. However this time I have something else in mind – namely, NoSQL DBs.

I think NoSQL DBs are a part of a major paradigm shift happening right now in IT industry and I want to have hands on experience with those technologies. Funny enough, unlike much hyped Web 2.0 or SOA this paradigm shift, which in my opinion is much bigger and more important than those two, happens almost unnoticed. I will write a post or two on the paradigm shift and NoSQL DBs soon.

There are Grails GORM plugins for several NoSQL databases: MongoDB, Riak, Redis, HBase, Gemfire.

Hbase is for huge data grinding facilities; it is too big for my needs. Gemfire is proprietary, so I am left with MongoDB, Redis and Riak each of which is quite good. I will think a bit more of this and I will describe my choice later in a separate post.

Presentation layer

Naturally, social applications use web technologies at their presentation layer. So will be Squirrel2 doing. I plan to use HTML5 and Rich Internet Application technologies.

In particular, I consider using jQuery, jQuery UI and plugins to them. I like very much architecture of jQuery and actually it is a sort of standard de-facto in modern web GUI technologies.

Also I plan to use Coffeescript language for writing JavaScript code. I consider latter a very promising technology and want to try it.

That’s all for today. I will describe my choice of tools and supporting technologies in the next post.

Advertisements

Read Full Post »

I myself may be considered predominantly Java developer and architect. I really love Java and it is my “weapon of choice”.

However recently I have attended “No fluff just stuff” (NFJF) conference in Dallas, TX. There were a number of sessions on Groovy and Grails and I have got really interested. Groovy provided elegant solutions to certain coding problems I always felt were somewhat ugly in Java. No offence – “nobody is perfect” as it was told in a famous movie.

Also I think an idea to blend seamlessly Groovy where I need its expression power and Java where I need its speed and wealth of APIs and libraries is very powerful. So I have got so interested that I consider using Groovy and Grails in my new personal project I’m contemplating.

As a part of my preparations I decided to do a small performance benchmark to see how Groovy will perform vs Java.

Yeah, I know there are many already. Here is very good one for example.  Unfortunately, it does not include Groovy++ which is a sort of performance-oriented version of Groovy. Also, I wanted to do comparison on problems meaningful to me. So I wrote small test programs in Groovy, Java and Groovy++ and run them on my laptop which I use for writing this post. It has Athlon II X2 M300 two core CPU and 4GB RAM and runs Ubuntu 11.04.

I have used Groovy 1.7.4. It is not the newest version, but it comes with Ubuntu 11.04 and this saved me hassle installing it manually. Also, I prefer to hope to be pleasantly surprised by performance of newer versions 🙂

I have used Groovy++ 0.2.27 which is again not the latest and greatest, but it works with Groovy 1.7.4. I have used Java JDK 1.6.

The first task (task A) was generating XML file. I was lazy and borrowed the code for Groovy and Java from “Groovy in action” – an excellent book, by the way.

The second task (task B) was reading a file which contained a full text of “Peace and war” by Lev Tolstoy, splitting each line on white spaces, concatenating the tokens back in one string and writing the string in sysout. I found that Groovy XML generating code can’t take advantage of Groovy++, unfortunately. But this was sort of expected – Groovy builders make use of dynamic typing which is not optimized by Groovy++. Also, I had to make certain adjustments to  make the code compiling in Groovy++.

Each task was repeated 100 times to make sure that Java JVM could take advantage of HotSpot feature.

So here are the results:

Language

Task A, ms

Task B, ms

Groovy

1492

23023

Java

651

6139

Groovy++

1490

14159

Couple of surprises:

  • Groovy is not so much slower than Java; at least not dramatically slower
  • Groovy++ is not as fast as I expected

What was not a surprise – Groovy code is substantially more compact and elegant than corresponding Java code which makes developer productivity higher providing the developer is good enough to handle well a dynamically typed language without many type-related bugs. Groovy line count is 58 and Java line count is 117! Twice less than Java! This is a big difference and, potentially, big money.

Overall, the result is encouraging.

Here is Java code:

package tryjava;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
public class TryJava {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args){
        TryJava w = new TryJava();
        w.doTaskA();
        w.doTaskB();
    }
    public void doTaskA() {
        long startTime = System.currentTimeMillis();
        for(int k=0; k<100; k++){
            try{
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = factory.newDocumentBuilder();
                Document doc = (Document) builder.newDocument();
                Element numbers = doc.createElement(“numbers”);
                Element description = doc.createElement(“description”);
                doc.appendChild(numbers);
                numbers.appendChild(description);
                description.setTextContent(“Squares and factors of 10..15”);
                for (int i=10; i<=15; i++){
                    Element number = doc.createElement(“number”);
                    numbers.appendChild(number);
                    number.setAttribute(“value”, String.valueOf(i));
                    number.setAttribute(“square”, String.valueOf(i*i));
                    for (int j=2; j<i; j++){
                        if (i % j == 0){
                            Element factor = doc.createElement(“factor”);
                            number.appendChild(factor);
                            factor.setAttribute(“value”, String.valueOf(j));
                        }
                    }
                }
                DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
                DOMImplementationLS impl = (DOMImplementationLS)registry.getDOMImplementation(“LS”);
                LSSerializer writer = impl.createLSSerializer();
                String str = writer.writeToString(doc);
                System.out.println(str);
            }
            catch (Exception e){
                System.err.println(“Exception occured : “+e);
            }
        }
        long endTime = System.currentTimeMillis();
        System.out.println(“>>>>> Task A execution time is : “+(endTime – startTime));
    }
    public void doTaskB(){
        List<String> stringListIn  = readFile();
        List<String> stringListOut = new ArrayList();
        int tokenCount = 0;
        long startTime = System.currentTimeMillis();
        for (int i=0; i<100; i++){
            for(String s : stringListIn){
                StringBuilder sb = new StringBuilder(80);
                String[] tokens = s.split(” “);
                tokenCount = tokenCount + tokens.length;
                for(String t : tokens){
                    sb.append(t);
                }
                stringListOut.add(sb.toString());
            }
        }
        long endTime = System.currentTimeMillis();
        System.out.println(“>>>>> Task B execution time is : “+(endTime – startTime));
        System.out.println(“>>>>> Task B string count      : “+ stringListOut.size());
        System.out.println(“>>>>> Task B token  count      : “+ tokenCount);
    }
    private List<String> readFile(){
        List<String> retVal = new ArrayList<String>();
        try{
            FileReader fr = new FileReader(“/home/vlad/mygroovy/perf/text_0040.txt”);
            LineNumberReader lr = new LineNumberReader(fr);
            String line = null;
            while((line=lr.readLine()) != null){
                retVal.add(line);
            }
        }
        catch (IOException e){
            System.err.println(“Exception occured : “+e);
        }
        return retVal;
    }
}

Here is Groovy code:

class TryGroovy {
    def static main(args){
        def w = new TryGroovy()
        w.doTaskA()
        w.doTaskB()
    }
    def doTaskA(){
        groovy.xml.MarkupBuilder builder = new groovy.xml.MarkupBuilder()
        def startTime = System.currentTimeMillis()
        100.times{
            builder.numbers{
                description ‘Squares and factors 10..15’
                for (i in 10..15){
                    number (value:i, square:i*i){
                        for(j in 2..<i){
                            factor (value:j)
                        }
                    }
                }
            }
        }
        def endTime = System.currentTimeMillis()
        println “>>>>> Task A execution time is : “+(endTime – startTime)
    }
    def doTaskB(){
        ArrayList stringListIn  = []
        ArrayList stringListOut = []
        def tokenCount = 0;
        def reader = {
            StringBuilder sb = new StringBuilder(160)
String s = it;
            ArrayList tokenList = s.split(‘ ‘)
            tokenCount = tokenCount + tokenList.size()
            tokenList.each({sb.append(it)})
            stringListOut << sb.toString()
        }
        File f = new File(‘text_0040.txt’)
        def startTime = System.currentTimeMillis()
        100.times() {stringListIn = f.eachLine(reader)}
        def endTime = System.currentTimeMillis()
        println “>>>>> Task B execution time is : “+(endTime – startTime)
        println “>>>>> Task B string count      : “+ stringListOut.size()
        println “>>>>> Task B token  count      : “+ tokenCount
    }
}

Here is Groovy++ code:

class TryGroovy2 {
int tokenCount =0
ArrayList stringListOut  = []
    ArrayList stringListIn  = []
    def static main(args){
        def w = new TryGroovy2()
        w.doTaskA()
        w.doTaskB()
    }
@Typed (TypePolicy.MIXED)
    def doTaskA(){
        groovy.xml.MarkupBuilder builder = new groovy.xml.MarkupBuilder()
        def startTime = System.currentTimeMillis()
        100.times{
            builder.numbers{
                description ‘Squares and factors 10..15’
                for (i in 10..15){
                    number (value:i, square:i*i){
                        for(j in 2..<i){
                            factor (value:j)
                        }
                    }
                }
            }
        }
        def endTime = System.currentTimeMillis()
        println “>>>>> Task A execution time is : “+(endTime – startTime)
    }
@Typed
    def doTaskB(){
        def reader = {
            StringBuilder sb = new StringBuilder(160)
String s = it;
            List tokenList = Arrays.asList(s.split(‘ ‘))
            this.tokenCount = tokenCount + tokenList.size()
            tokenList.each({sb.append(it)})
            this.stringListOut << sb.toString()
        }
        File f = new File(‘text_0040.txt’)
        def startTime = System.currentTimeMillis()
        100.times() {this.stringListIn = f.eachLine(reader)}
        def endTime = System.currentTimeMillis()
        println “>>>>> Task B execution time is : “+(endTime – startTime)
        println “>>>>> Task B string count      : “+ stringListOut.size()
        println “>>>>> Task B token  count      : “+ tokenCount
    }
}

Read Full Post »