Wednesday, 29 February 2012

Typed Integers

I really like the idea of typed integers. For example, if you a number representing the number of cats and a number representing a number of dogs it is possible to add these together.  In a typed integer world it would not be possible and throw an error upon compilation.  I think this would be a big improvement for API safety and also a method of documentation.  There is nothing worse than a method with a structure like #foo(int, int) which is difficult to understand without reading or documentation every time.

In general use this would be suicide in a managed language where the overhead of an object for every int could mean a huge jump in memory usage and GC wouldn't be worth the improvements.  The actual implementation in Java would also be extremely ugly, for example:

class EventID {
  private final int id;
  public EventID(int anID) {
    id = anID;
  }
}

The class doesn't even contain basic methods like a way to get the ID, compare or hash it which with an int you get for free and it is still a fair wedge of code.  Lombok's @Data annotation can really improve classes like this and make the language feel more declarative.

I have found the best language to implement this is c++, the following is my proof of concept implementation:

template
class TypedInt
{
public:
  const int value;

  TypedInt(int v) : value(v) {};

  TypedInt operator + (TypedInt num)
  {
    TypedInt result(value + num.value);

    return result;
  }

  TypedInt  operator = (const int other)
  {
    TypedInt result(other);

    return result;
  }
};

This allows the following usage:

struct eventid {};

typedef TypedInt EventId;
  
EventId i = 2, j = 3;

EventId result = i + j;

Overall this feels natural to use.  If I was actually using class then the other operators such as == could be implemented without problems. 

One of the benefits of c++ is that an object wrapping an int does not take more memory than an int would, during compilation this abstraction is apparently stripped away.

Sunday, 26 February 2012

Compatible Images

A couple of weeks ago I was tasked with improving the performance on a legacy java swing application that was really crawling.  It would repaint the whole screen on any event, which it could receive a lot of, and painting the whole screen was really slow.  By using compatible images instead of the default kind of image read by ImageIO, the painting code was sped up by a factor of 70 and the event frequency was a non-issue.  The whole change was about 10 lines of code, much less than that to make the software use the graphics clip.

If you are having an issue with graphics performance make sure you try compatible images before trying anything else since it is so easy to introduce.

Before deploying to site I was worried that the speed up I was seeing was in some way down to my dev machine working well with compatible images so I wrote the tool below to test if the improvement was the same which it was.  Some notes:
  1. The tool requires an image.  When I attempted to create an in-memory image there was no difference in run times.
  2. Results are printed on the command line so remember to use java.exe and not javaw.exe
  3. I went to some effort so that this program was a single class to make it easy for the support guys to run.  I don't usually like to implement Runnable on a class that isn't just a Runnable.

How Much Architecture is Enough?

In the past I have often wondered if I have provided enough architecture for the software team to work to.  Conversely I always like to leave enough room to maneuver for the guys to do design for their own parts of the software, I would really hate it if I was working on a project where everything was defined and all I needed to do was "code in the blanks".

The idealist in me wants to provide just enough architecture to start work at all, and emergency design will do the rest.  I have found this is not how great software is made.  When everyone is left somewhat to their own devices, the code starts to lose coherence.  Everyone will code their own mini framework that will not interact well with other stories or allow extension for all requirements.  This is natural as everyone might not be aware of all requirements for the project.

The answer to this is pretty simple in practice, whenever two or more stories meet the following criteria you need some architecture:

1. Other code interacts with the product of a story.  
For example some kind of remote or local service or data.  In my current work we do a lot of inter-process communication.  This is really a technical detail, web services or in-process framework meets the same criteria.  Whatever it is, it needs some documented architecture.  The documentation part here is important, it should be simple to find look-up the exposed interfaces with arguments including valid values, errors etc.  This rule tends to reduce errors and confusion (more errors) occurring from not knowing about or not understanding .

2. Two or more stories are similar

For example, two kinds of message or input that could be handled in the same way or are similar enough to be categorised together.  Polymorphism and/or inversion of control can be used to have a central mechanism handle these in a reusable way.  This rule tends to reduce the overall amount of code and improve code quality. 

These two scenarios are sum up pretty much of every time where I had wished I had provided some architecture before work commenced