Incompressible Java, PI day

Weiqi Gao reminded me that today is “PI Day”; that along wouldn’t warrant a post here, but the Java snippet for estimating the value of PI rather inefficiently, did:

[weiqi@gao] $ cat PI.java
public class PI {
public static void main(String[] args) {
double sum = 0.0d;
for (int i = 1; i < 64000; i++) {
sum += 6.0/(i*i);
}
System.out.println(Math.sqrt(sum));
}
}
[weiqi@gao] $ javac PI.java
[weiqi@gao] $ java PI
3.1415525815597167

The inefficiency of the PI estimate didn't bother me - rather it was the inefficiency of the text of the program. This is a a good example of the "incompressibility" of Java; there are a lot of words and symbols in there. Contrast that with a bit of Ruby:

ruby -e "print (1..64000).inject(0.0) { | sum, i | sum + 6.0 / (i*i) } ** 0.5"

3.141577732895

The difference in the answer is from the different underying floating point data types. The textual difference is easy to talk your way around for a small program like this. But we've found that as our applications grow, the amount of Java code grows at a frightening rate compared to the functionality therein. We work around that with great tools (Eclipse, IDEA), and accept it as a trade off to the strong library support and abundance of developers. But the language itself...

.NET Traction at Microsoft?

According to this article from Richard Grimes, it appears that .NET has not gained as much traction inside Microsoft as anticipated:
http://www.grimes.demon.co.uk/dotnet/vistaAndDotnet.htm

“My conclusion is that Microsoft has lost its confidence in .NET. They implement very little of their own code using .NET. The framework is provided as part of the operating system, but this is so that code written by third party developers can run on Vista without the large download of the framework. Supplying the .NET runtime for third party developers in this way is similar to Microsoft supplying msvbvm60.dll as part of XP.”

I think his conclusion is a bit overreaching, but this isn’t a big deal to me either way, and I’m neither a raving Microsoft fan nor a rabid Microsoft detractor.

However, this is good news in at least one important way:

To the extent Windows itself is not built on .NET, that in a sense leaves more room for other, non-.NET runtime environments to flourish as first class citizens, leaving more room for Java (we ship a commercial Java application, so that’s good…) and also for other currently and upcoming dynamic language runtime environments.

Direct Manipulation Java Swing GUI Talk

At the St. Louis Java User Group meeting on Sep. 8, 2005, I gave a talk on building “Direct Manipulation” user interfaces with Java Swing. Here are the slide and code from that talk. The slides are quite limited, as the talk was spent almost entirely in the code – this is the kind of talk I prefer to give, with a lot of technical depth crammed in to the time allotted. Unfortunately this makes it somewhat less useful for people who weren’t at the talk; I’ve thought of making a “screencast” of the presentation for that reason.

Source Code and Presentation: SwingTalk.zip

Update: The sample code that got the most attention was the “flying boxes” code in the swingtalk.ordering package; you can try it now via Web Start.

Update: I presented this code again at the St. Louis Code Camp on May 5, 2007. Alex Miller picked it up and revamped it to use the new Swing Application Framework stuff coming (most likely) in Java 7.

JAR Bloat

I am surprised at how large the main client application JAR file is on my current Java project. I have a pile of source code which I have written over the last few months; it contains no generated code and no outside code (that stuff is in other jars).

This body of code results in a 506K JAR file. About 10% of that is because it is a “signed JAR” (An aside: it appears that signed jars actually actually sign each thing inside the JAR… much far higher overhead than .NET’s igned assemblies, which sign the whole thing as a chunk. I think .NET is on to something good with Assemblies with Sun missed with just-a-bunch-of-classes-in-a-JAR. Of course the latter has significant advantages also.)

Without the signing, the JAR is about 450K.

Javac optimization is on. There are ~350 classes in the JAR file. The JAR is compressed; wihtout compression it is around a megabyte.

– debug is on, so I get more helpful stack traces from the field when errant software somehow escapes our highly rigorous release process. Turning off debugdrops it to 424K signed / ~380K unsigned.

These numbers all seems enormous. The source code for the contents of this JAR, is only ~800K, and contain considerable comments, private identifiers, etc. My mental model of compilation suggests that it would produce tightly packed bytecode that tersely captures the executable essence of the source code in a small fraction of the bytes. This appears to not be the case.

More Bowling

In my last post, I presented an enhancement to a "bowling score calculator" problem being discussed on the Extreme Programming Mailing List. My solution extended a not-very-OO
solution presented here; though not object oriented, it was short and clear. I generally write intensively OO code, so I found this interesting.

A contention on the list, though, was that the procedural solution could not be extended to support more features easily. Today I’d added even more features, just to see if this is true:

  • Know how many pins are standing, and prevent the caller from knocking down
    more pins than are up.
  • Know which rolls occurred in which frame; be able to answer "what were
    the rolls in frame N?"
  • Present an HTML representation of the state of the game after each roll.

As usual, I added this features a test at a time a bit at a time. It turned out to be easy to keep track of which rolls go in which frame. The updated source code can be downloaded: bowling-java-3c.tgz and is also on github. As before the download includes the tests also. I’ve renamed a few things for greater clarity. (I’ve updated the file a couple of times since posting it, to fix a problem in the final output, and separate some tests I had combined.)

I was surprised to find that adding these features didn’t add much complexity to the code. When I look at this code, it cries out to have a class of some kind extracted – but I’ve tried extracting, for example, the idea of a Frame and been unsatisfied. Perhaps I’ll explore that more another day. These variable:

  private int[] frameScores = new int[NUM_FRAMES];
  private int[] firstRollInFrame = new int[NUM_FRAMES + 1];
  private int scoredFrame;
  private int finishedFrame;

could form the starting point for that, like so:

class Frame {
    private int score;
    private int firstRoll;
    private boolean scored;
    private boolean finished;
}

The Game class is in its entirety is
available here (syntax highlighted HTML) or in the download above.

I implemented the HTML rendering of frames without aid of test cases. The code is included
in the download above, and produces output like the sample run below. The output looks
much better when not included inside a WordPress post – the sample below is
partially mangled.

The main
loop of the demo program biases the random numbers toward high scores:

        while (!game.gameOver()) {
          // Bias our guy toward good rolls:
          int n = rnd.nextInt(game.pinsStanding() + 4);
          int pins = Math.min(n, game.pinsStanding());
          renderer.tellAboutPins(pins);
          game.roll(pins);
          renderer.printGame(game);
        }

Rolling… 7 pins

7

Rolling… 3 pins

7 3

Rolling… 10 pins

7 3

20

10

Rolling… 4 pins

7 3

20

10
4

Rolling… 2 pins

7 3

20

10

36

4 2

42

Rolling… 10 pins

7 3

20

10

36

4 2

42

10

Rolling… 0 pins

7 3

20

10

36

4 2

42

10
0

Rolling… 3 pins

7 3

20

10

36

4 2

42

10

55

0 3

58

Rolling… 10 pins

7 3

20

10

36

4 2

42

10

55

0 3

58

10

Rolling… 3 pins

7 3

20

10

36

4 2

42

10

55

0 3

58

10
3

Rolling… 5 pins

7 3

20

10

36

4 2

42

10

55

0 3

58

10

76

3 5

84

Rolling… 10 pins

7 3

20

10

36

4 2

42

10

55

0 3

58

10

76

3 5

84

10

Rolling… 4 pins

7 3

20

10

36

4 2

42

10

55

0 3

58

10

76

3 5

84

10
4

Rolling… 0 pins

7 3

20

10

36

4 2

42

10

55

0 3

58

10

76

3 5

84

10

98

4 0

102

Rolling… 1 pins

7 3

20

10

36

4 2

42

10

55

0 3

58

10

76

3 5

84

10

98

4 0

102

1

Rolling… 1 pins

7 3

20

10

36

4 2

42

10

55

0 3

58

10

76

3 5

84

10

98

4 0

102

1 1

104


Comments welcome, via email (address below).