Thursday Sep 24, 2009

Second Order

I had "that argument" with someone again recently. You know, the one about Java performance vs. C code. It's an argument I am very tired of having and I'm tempted to go "Barney Frank" on the next person to suggest there's a difference that matters.

One of the supposed C advantages is supposed to be that it offers greater opportunity for optimization. Maybe I have been looking at the wrong code lately but I see very little code these days that instruction-wise optimization, inline assembly or hand tweaking makes better. The biggest problem is not that careful optimization of small functions doesn't produce speed improvements but that those speed improvements are, overall, of marginal benefit. Here's some really bad code:

StinkoCode.java
static void main(String[] args) {

    List sortedArgs = new LinkedList();

    for(String arg : args) {
        sortedArgs.add(arg);
        Collections.sort(sortedArgs);
    }

    System.out.println(sortedArgs);
}

Even though this is just a contrived example, yes, I do regularly see code this inefficient. Would optimizing the sort() operation have much impact on the overall behaviour of this program? How about the choice of LinkedList? Would using a bulk insertion strategy such as addAll() help? If there are many arguments passed in the biggest gains would almost certainly come from sorting the arguments only once and possibly using a different data structure to store the strings. Let's try that again:

BetterCode.java
static void main(String[] args) {

    String[] sortedArgs = Arrays.copyOf(args, args.length);
    Arrays.sort(sortedArgs);

    System.out.println(Arrays.asList(sortedArgs));
}

As cautions against premature optimization suggest, is critical to carefully examine the causes your hot code is burning so many cycles before optimizing. Frequently the real problem is with the calling code and not the exact piece of code which shows up in the profiler as your hot spot. When planning optimizations it's usually best to look "up the stack" and evaluate the usage pattern for the bottleneck code being called before diving in to make a targeted fix. Most likely, at best, you'll only get a marginal improvement by making a local optimization. For the really big wins you should be focusing on the higher order causes.

About

mduigou

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today