Java String Concatenation

March 15, 2007

I was having a discussion with a co-worker today regarding String concatenation in Java. Somewhere along the line, I was told that the Java + operator, when applied to String, was slow when compared to using the append method of StringBuffer or StringBuilder. Tuns out this is a myth, sort of. I wrote a class to test it. This will first concatenate a String 100 times using the + operator, and then build the same string using StringBuilder's append method:

public class StringTest {

    private int iterations;

    public static void main(String[] args) {
        StringTest test = new StringTest(100);
        for(int i = 0; i < 10; i++) {
            test.concat();
            test.append();
        }
    }

    public StringTest(int iterations) {
        this.iterations = iterations;
    }

    private void concat() {
        String foo = "";
        long start = System.currentTimeMillis();
        for(int i = 0; i < iterations; i++) {
            foo += "foo";
        }
        System.out.println("String concat took "+(System.currentTimeMillis()-start)+" ms");
    }

    private void append() {
        StringBuilder sb = new StringBuilder();
        long start = System.currentTimeMillis();
        for(int i = 0; i < iterations; i++) {
            sb.append("foo");
        }
        System.out.println("String append took "+(System.currentTimeMillis()-start)+" ms");
    }

}

The results of this test are:

String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms
String concat took 0 ms
String append took 0 ms

So, when concatenating 100 strings, using the + incurs no significant overhead. But, if we run the same test concatenating 10000 String instead, these are the results:

String concat took 1812 ms
String append took 0 ms
String concat took 1766 ms
String append took 0 ms
String concat took 1766 ms
String append took 0 ms
String concat took 1812 ms
String append took 0 ms
String concat took 1750 ms
String append took 0 ms
String concat took 1828 ms
String append took 0 ms
String concat took 1750 ms
String append took 0 ms
String concat took 1750 ms
String append took 0 ms
String concat took 1782 ms
String append took 0 ms
String concat took 1750 ms
String append took 0 ms

So the Java String concatenation myth is rooted in fact, but as stated on this article on Java Practices, you should use the + operator whenever you are manually concatenating a bunch of Strings, like String foo = "foo"+x+"bar"+y+"baz"+z;, because for that few of a number of Strings, the code is cleaner using the + operator and the overhead of the operator is insignificant. But, if you are pulling data from an external source and building a large String by concatenating many smaller Strings, the StringBuilder would be better to use.

Posted in Technology | Tags Java | 6 Comments

Ruby on Rails vs. J2EE

March 15, 2007

I know, I know, here we go again, another blog post about Ruby on Rails vs. J2EE. Get ready for a flame war. Why do I say that? Because that's what Ruby on Rails vs. J2EE discussions usually turn into. But today I ran across a really good short comparison of Rails and J2EE by Bruno Fernandez-Ruiz. Here's a great quote:

If you have been doing pure web frontends in Java using JSP and JDBC, well, sorry, I think you should go back and examine Python (Django), Ruby (Rails) and PHP (Yellow Duck, BlueShoes) and stop wasting your time.

But don't take that quote out of context, because here's another thing he says:

J2EE is a distributed component on steroids - so if you don't need distributed components, you don't need J2EE. But if you rely on JMS, JCA, JTA and distributed components, then Rails is not your medicine.

And to sum it up:

Bottom line, Rails and J2EE cover different needs and developer populations. There will surely always be an overlap - and over time they will both mutate to copy features from each other.

This points out how Rails and J2EE are different tools, and one can be better than the other, depending on the requirements of the application. Rather than spending time defending whichever one you happen to be better at, spend time learning more about the other, and learning about which kinds of applications each is appropriate for.

Another thing to point how is that how each platform has the opposite challenge. J2EE has the problem of dealing with how to scale down in terms of complexity. Simply put, simple applications are more difficult than they need to be with J2EE. Rails on the other hand has the problem of dealing with how to scale up in terms of complexity. Rails is great for straight-forward database-backed web applications, but what about dealing with applications that have complex transaction management issues? Using either framework in the wrong situation will result in your application falling victim to the Bittersweet Motel Syndrome.

Posted in Technology | Tags J2EE, Ruby, Java, Rails | 0 Comments

Guice Hello World

March 12, 2007

A new project called Guice (pronounced Juice, but starts with a G instead of J because it's Googlerrific) has been created. Guice aims to be a better Dependency Injection (DI) framework for Java. The de facto DI framework for Java is currently Spring. Spring provides a lot of things besides DI, but I think DI is it's main selling point. I often use Spring in projects only for it's DI. I use Stripes as my Web MVC framework and Hibernate as my ORM framework, so I don't need Spring's MVC layer or JDBC Template. I do use Spring's declarative transaction management and hibernate configuration features, but that's only because once you start using Spring for DI, it's easy to use those features as well, but they could be easily replaced.

The main disadvantage of Spring, in my opinion, is the amount of XML files that you have to create to configuration you application. The thing I dislike most about the XML configuration is that it is not type safe, and just like Bob Lee says:

I'm using a strongly typed language; why would I want to throw all of this perfectly good type information away? If I wanted that, I'd use Ruby.

I don't think he meant that statement as a knock against Ruby, he's just saying that if you are programming in Java, then you want to use type safety as much as possible. Annotations and Generics, features added to Java in Java 5, can allow you to do that, and Guice aims to provide dependency injection via Annotations rather than XML.

So I decided to take a look at Guice, and although the documentation is pretty good, it doesn't have a working "Hello World" type example to get you going, so I figured I would provide one here. I encourage you to play along at home.

First, download Guice, setup a new project in your favorite IDE, and add guice-1.0.jar to your classpath. What we're going to do is create a basic domain model object, Foo, and a DAO-like Manager for Foo, and then create a controller that depends on the FooManager, and has that dependency set using Guice. So here we go. Create the Foo class:

public class Foo {

    private Long id;
    private String name;

    //Generate and getters/setters in your IDE

}

Then create the interface for the FooManager:

public interface FooManager {

    public Foo get(Long id);
    public void save(Foo foo);

}    

Then create an implementation of the FooManager. In real life, you might implement this with an ORM framework like Hibernate, but this simple little thing serves the purpose for this example:

public class FooManagerImpl implements FooManager {

    private static Long fooSequence = 1l;
    private static final Map<Long, Foo> foos = new HashMap<Long, Foo>();

    public Foo get(Long id) {
        return foos.get(id);
    }

    public void save(Foo foo) {
        if(foo == null) return;
        if(foo.getId() == null) {
            foo.setId(fooSequence);
            fooSequence++;
        }
        foos.put(foo.getId(), foo);
    }
}

And for the last part of our app, we'll create a controller that calls our manager. This controller is sort of like what a controller in a web app might be like:

public class FooController {

    private FooManager fooManager;

    //----- Controller Actions -------------------------------------------------
    public Foo create(String name) {
        Foo foo = new Foo();
        foo.setName(name);
        fooManager.save(foo);
        return foo;
    }

    public Foo retrieve(Long id) {
        return fooManager.get(id);
    }

    //----- Getters/Setters ----------------------------------------------------
    public FooManager getFooManager() {
        return fooManager;
    }

    @Inject
    public void setFooManager(FooManager fooManager) {
        this.fooManager = fooManager;
    }

}

You can see that with the annotation Inject on the fooManager setter, we are asking Guice to inject a fooManager instance into our controller. Continuing with the web app like architecture of our app, we'll create a dispatcher. In a real app, this would be the FrontController responsible for directing the request to be handled by the appropriate controller action, but for our simple app, we'll just hard code 2 controller action methods to be called:

public class FooDispatcher {

    public static void main(String[] args) {

        FooController controller = new FooController();
        Injector injector = Guice.createInjector(new FooModule());
        injector.injectMembers(controller);

        //Our action is now injected with a FooManager, so let's use it
        Foo foo = controller.create("Bar");
        Foo bar = controller.retrieve(foo.getId());
        System.out.println("bar.name => "+bar.getName());

    }

}

As you can see here, we've now got some Guice specific code. First we create an injector using the FooModule. The FooModule is a class we create that serves as the configuration for Guice, we'll get to that in a minute. The creation of this injector is something that you would do once, probably upon application startup. Then, we ask the injector to inject our controller instance with its dependencies. The simple Inject annotation we added on the setFooManager method of our controller is all the info the injector needs to set up our controller. Next you see we call 2 action methods, one to create a new Foo instance, and then another to retrieve it.

So let's look at the FooModule, which is where we do our Guice configuration:

public class FooModule extends AbstractModule {

    protected void configure() {
        bind(FooManager.class)
            .to(FooManagerImpl.class)
            .in(Scopes.SINGLETON);
    }

}

What this says is that when something needs a FooManager injected into it, use a singleton instance of FooManagerImpl to fulfill that dependency. We can actually use annotations to further simplify this configuration. First, we add the ImplementedBy annotation to the FooManager interface:

@ImplementedBy(FooManagerImpl.class)
public interface FooManager {

    public Foo get(Long id);
    public void save(Foo foo);

}

This basically says to Guice that we want FooManagerImpl to be the default implementation class for FooManager. Also, we can specify that by default we want FooManagerImpl to be a singleton:

@Singleton
public class FooManagerImpl implements FooManager {

    private static Long fooSequence = 1l;
    private static final Map<Long, Foo> foos = new HashMap<Long, Foo>();

    public Foo get(Long id) {
        return foos.get(id);
    }

    public void save(Foo foo) {
        if(foo == null) return;
        if(foo.getId() == null) {
            foo.setId(fooSequence);
            fooSequence++;
        }
        foos.put(foo.getId(), foo);
    }
}

Now, we can modify our module to look like this:

public class FooModule extends AbstractModule {

    protected void configure() {
        bind(FooManager.class);
    }

}

An now when we re-run our FooDispatcher, every thing still works. In real life, there would be some core mechanism in the web app framework to handle creating the injector and injecting dependencies into the controller instances, and I'm sure it would be fairly trivial to implement that into Stripes.

Although some people don't think Guice is going to replace Spring, I think for projects where Spring is being used mostly for DI, we will see Guice or something like it start to replace Spring. I also predict that in response to this, Spring will be forced into incorporating an annotation-based configuration mechanism into its core codebase in order to remain popular in the oncoming wave of Annotation based "zero" configuration frameworks like Stripes, Struts 2 and Hibernate.

UPDATE: Monday, March 12, 5:18pm

Thanks to a tip from Bob, I've discovered that once you have every thing configured by annotations, as we do at the end of this example, you can completely remove the FooModule, which gives you the code like this in the dispatcher:

public class FooDispatcher {

    public static void main(String[] args) {

        FooController controller = new FooController();
        Injector injector = Guice.createInjector();
        injector.injectMembers(controller);

        //Our action is now injected with a FooManager, so let's use it
        Foo foo = controller.create("Bar");
        Foo bar = controller.retrieve(foo.getId());
        System.out.println("bar.name => "+bar.getName());

    }

}

The point is that for any class that you can configure with annotations, you don't need to explicitly define them in a module, or anywhere. So take an app with 50 different manager classes, all you would have to do is create a manager interface, annotate it as a singleton, and then create the default implementation. Compare that with a minimum of 50 bean entries in a Spring context configuration XML file, and you can see how Guice can really start to simplify your configuration.

Posted in Technology | Tags Spring, Hibernate, Stripes, Java, DependencyInjection, Guice | 28 Comments

Improving productivity instead of outsourcing

February 21, 2007

I just got back from the Northern Virgina Ruby Users Group meeting meeting. It was the first meeting I have been to. I was expecting a dozen or so people to be there, I would say there was more like 60 people. Chad Fowler was the speaker and he gave an excellent talk about writing quick and clean code with Rails. Really, it was just a collection of examples of how to write clean code with Rails. The main point of the talk is that Rails is built on Ruby and that with Ruby you can do a lot of powerful things. You should master the Ruby language and then use the power of Ruby to the fullest to help you write better Rails code.

Another point he made is that "Java is a language that was created for idiots". That is a funny and inflammatory statement, but what he means is that Java doesn't allow you to do stupid things like re-define what the + operator (or in the case of Ruby, method) does, because things like that are dangerous. For example, say you create this Ruby code and put it somewhere in your app so that it executes before the rest of your code (like at the point your whole app is initialized, for example):

class Fixnum
    def + arg
        self*arg
    end
end

So then what happens when you run 1+2? You get 2. Why? Because you have redefined the + method (that's right, the name of the method is "+") to now multiply the argument by self, rather than add it. So that is stupid, and idiots do stupid things. So Java doesn't let you do that, because it thinks you are an idiot and it's job is to protect you from doing stupid things. Ruby, on the other hand, assumes you are not an idiot and you will not do stupid things. It allows you to do pretty much anything you want, because you probably have a good reason for doing so, because, after all, you're not an idiot. He did go on to clarify that if you program in Java, that doesn't make you an idiot, just a programmer who uses a language built for idiots.

There were lots of other Ruby/Rails specific things that he points out, hopefully he'll put the slides online. But one last thing that I found interesting that came up in the discussion was that he thought Paul Graham once said "Why would I hire offshore developers to write code when I could just hire someone to do it in Rails?". The point being that you can get more for your development money one of two ways: Pay less per hour or pay someone to accomplish the task in less hours. $100/hour x 10 hours = $10/hour + 100 hours, what's the difference.

It's an interesting point, and I really like Paul Graham's writing, so I did some googling to find the original article, which I think I found and it is titled The Venture Capital Squeeze. I think the actual quote that he is referring to is:

I think a better model for the future is David Heinemeier Hansson, who outsourced his development to a more powerful language instead. A lot of well-known applications are now, like BaseCamp, written by just one programmer. And one guy is more than 10x cheaper than ten, because (a) he won't waste any time in meetings, and (b) since he's probably a founder, he can pay himself nothing.

Posted in Technology | Tags Ruby, Java, Rails | 2 Comments

The Power of Dynamic Methods

February 14, 2007

Today I was writing some Java code and needed to make methods like this:

@Transient
public String getThingsAsString() {
    if(things != null) {
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for(Thing t: things) {
            if(!first) {
                sb.append(", ");
            } else {
                first = false;
            }
            sb.append(t.getName());
        }
        return sb.toString();
    }
    return null;
}

Basically, I have an object that has a Collection of Things objects, and I need to print the name of each Thing in a comma-separated list. I have several different Collections and so I need to repeat this for each one. I could "simplify" this by creating an interface that all of my different objects like Thing implement, for example calling it NamedEntity. This means that each one of these objects are guaranteed to have a getName() method. After creating that interface and modifying all the object so that they implement it, I would write a utility method to print a NamedEntity as a String. So then each above method would look like:

public String getThingAsString() {
    return NamedEntityUtil.getNamedEntitiesAsString(things);
}

But this still means that I have to create a getXXXAsStringMethod for each collection. I could just call the utility method when I need the string, but the problem is that I need this string within JSP pages, and you can't call the static methods from a JSP without resorting to scriplets. This is especially a pain because it is difficult to mix JSTL and scriptlets.

So what could you do if you need to do this in Rails? Well for starters, you can use one line of Ruby code to do it:

things.collect {|t| t.name}.join(", ")

You could also create one view helper to make the syntax a little cleaner, and then re-use it. Ths view helper method would be:

def join_names(things, sep=", ")
  things.collect {|t| t.name}.join(sep)
end

And look at that, we easily can now optionally pass a different separator. But that's not the point I want to illustrate in this post. Let's say for some reason in Rails we really needed to create various method to print the various collections as strings. Well that would be easy too. We would just put this inside of our class that has a Collection of things:

["things", "other_things"].each do |name|
  define_method("#{name}_as_string") do self.join_names(self.send(name)) end
end

What this ruby magic does is dynamically create methods for each collection. It allows you call methods like this:

whatever.things_as_string
whatever.other_things_as_string

Like I said, you probably wouldn't really do this for this example, but the point here is that with Ruby, you can write code that writes code, and that can be very powerful.

I first heard of this concept in the book Hackers and Painters by Paul Graham. This is the best book on programming I have ever read, and if you haven't read it, go out and buy it and read it. It actually isn't very technical. It doesn't teach you any specific programming techniques, but it's just a great book. My favorite chapter is Why Nerds Are Unpopular.

In a chapter called Beating the Averages, for which the full text is available on Paul Graham's website, like many of the chapters of the book, he talks about how Lisp macros are programs that write programs, and at the time, it sounded like a great idea, but I just didn't get it. He said:

Programs that write programs? When would you ever want to do that? Not very often, if you think in Cobol. All the time, if you think in Lisp.

Code that writes code? When would you ever want to do that? Not very often, if you think in Java. All the time, if you think in Ruby.

Posted in Technology | Tags Hibernate, Ruby, Java, Rails | 0 Comments

<< Newer Articles   Older Articles >>