Monday, June 22, 2009

A good design is mandatory if you want good performance.

Now, I know that there has already been much ink spilt over premature optimisation and I thought I'd add my thoughts, mainly because it is still so relevant. I still see people not listening to Michael. A. Jackson's classic law:
  • “The First Rule of Program Optimization: Don't do it.
  • The Second Rule of Program Optimization (for experts only!): Don't do it yet.”
Michael A. Jackson

I think the problem stems from a question of value. Developers still see code that runs fast as somehow better than code that runs slow - so they will prefer a solution for example, that creates less objects because they see that solution as slow.

The "fast" version could be 10 times slower than the slow version, and 10 times sounds like a lot. Wow, you achieved a 10 times speed increase, that's got to be good right?

Not if the fast version takes 1 milli-second right? The slow version will take 10 ms. I challenge anyone to notice a 9 ms difference.

I've never heard anyone complain about some process taking 9 ms longer to complete. 9 ms!

To give you an example...

Consider the code:

long p = System.currentTimeMillis();
Agent[] objects = new Agent[1];
for (int i = 0; i <>
objects[i] = new za.co.sepia.ucc.core.model.Agent();
objects[i].setAgentId("hello");
}
System.out.println(System.currentTimeMillis()-p);
This code takes less then 1 ms to execute (printed difference is ZERO)... on my fairly powerful laptop with Java 6.

If I up the array size to 1000, it takes 31 ms...

I had to up the array size to 1000 to up the time taken to 31 ms. An array size of 1 is faster than an array size of 1000, it is in fact 30 times faster! Wow, I got a 30x speed improvement by reducing the array size. However, even with such an enormous factorial diference, the slow version still only takes 31 ms... That is 31 thousandths of a second.

Alright, granted, if you're doing hundreds, maybe thousands of these kind of operations then speed would start to be a factor. How often do you, in your daily software programming do you encounter situations where you're doing the same operation 10000 times...?

What I would like to see is developers change their priorities, and change their priorities in accordance with the third rule of optimisation, which I would like to add, and that is...

  • A well designed system is better than a badly designed system which runs 1% faster.
Why is it so important to had a well designed system with respect to performance?

Picture the following... at the end of your project you now want to increase performance. You have not optimised prematurely, but you do, unfortunately find that you now have a performance problem.

You run a profiler on your application and pin point the problem to be a particular component. Because your system is loosely coupled with good encapsulation you're able to rewrite that component quickly and easily, test it on its own to validate that the performance problem is no longer there, plug it back in and run the tests to validate your change.

But imagine if your system was badly designed...

While you would be able to pin point the source of the problem, chances are there's loads of dependencies on that component such that a simple rewrite will prove difficult. Furthermore, you would not be able to unplug it easily and rewrite it because there is tight coupling and little encapsulation. The bits of slow code are scattered all over the show. Maybe when you were designing you prioritised "performance"... funnily enough though, where you expected performance problems, none materialised.

I will always prefer a well designed system over one which is "fast".

In my experience, if you prioritise good design over performance, you will get a performing system in any case.

Wednesday, June 10, 2009

Is Java Dead?

Recently, on a local Java User Group the question was asked, should Java be my platform of choice. I was fairly surprised by the discussion that ensued. It was largely negative.

And why shouldn't it be, a language that is more than 10 years old, still hampered by its legacy, competing with cutting edge dynamic/scripting languages which seemed to have stolen a great deal of java's positivity. Java was debunked for being inelegant, hard to understand, unpredictable and old fashioned. While languages like Python were praised for their elegance, obviously better than java, far easier to learn and use.

So the question is, is Java that bad?

One or two examples were presented singling out auto boxing as a disaster, concurrency unpredictability and that perennial source of mirth, the try/catch/finally what exception is thrown? Personally, those "what happens in the above piece of code that you'll never write yourself?" are a waste of time. People single out the handful of confusing scenarios that you'll just not get in every day coding (unless you go looking).

The question is, what made java so attractive in the first place? and can those properties carry it forward? It had built in OO (yes, not _everything_ is an object I know, but close enough), it was simple, had none of the superfluous syntactic sugar of C++ and hit the ground running with a useful API, both for gui and other development and it was cross platform (ran on a VM).

The factor that is very often underestimated in proclaiming java's looming demise in face of more modern, dynamic and scripting languages is that only a small minority of developers actually keep up to date. Some have said, it's in the region of 20%, in my experience, it's probably about 15%. Those are the ones that don't teach themselves new technologies unless forced to. Also, I doubt those individuals see the pitfalls of java - the so called inelegance, is to my mind, significantly overblown. Yes, autoboxing has problems, but I've already seen the benefits of it, which outweigh the problems.

It would be remiss of me not to indicate that without the java platform, java would not be as viable as it is. In fact, some would say that without that java would be on the wain, and possibly "dead". One thing is for sure, that this is what makes java so viable and the only choice for any project of significant size and scale.

Personally, I cannot see java fading away or even losing it's dominant position in the market in the next 10 years. In ten years time, things will largely be the same as they are now. The new kids on the block however, will grow and will start to cut into java's domination, especially on the web and on the desktop, though I do think that google is going to keep java strong on the web (gwt and google app engine). Java will lose in these areas, but in it's mainstay, on the enterprise, it's not going anywhere.

Monday, June 01, 2009

Depency Injection/Inversion of Control - are they the same?

On the weekend I spoke to a friend and we were talking about the SOLID principles. We talked at lengh about Inversion of Control/Dependency Injection and how they are not the same thing. Trumpi was saying that you use dependency injection to achieve inversion of control, and that made sense to me. Then I consulted with another colleague about it and this colleague pointed that in order to achieve inversion of control then you will necessarily be doing some form of dependency injection. You will need to "inject" the dependency because the component requiring the dependency will only depend on an abstraction.

So in effect, they are the same thing. The different phrases describe the mechanism from different point of views, the one describes the behaviour (dependency injection), the other the structure (Inversion of Control).

What I also discovered as I opened the book, Agile Software Development, which I think, first explained the SOLID principles, presents the 'I' of SOLID as "Dependency Inversion", i.e. a combination of inversion of control and dependency injection. Which to my mind, is a better moniker as it describes the mechanism more accurately.

Thursday, May 28, 2009

Mockito is first mock framework you should consider

Having been stuck on jdk 1.4 for the last 3 years it came as something akin to a coming of age to step into modern java; and a most satisfying revelation has been mockito.

If you have used easy mock in the past you will be very pleased and probably quite excited when you encounter and start using mockito. It is totally awesome.

It is simple, intuitive, terse and has some very powerful features. It will gracefully handle almost all of your mocking needs. For example, it is possible to stub out selected methods on a live object.

To give you an example of mockito in action, to whet your appetite, here is a code snippet.

ConfigParams params = Mockito.mock(ConfigParams.class);
when(params.getInt(ConfigParamKey.AGENT_MATCH_TIMEOUT)).thenReturn(99);


So, it's fairly self explanatory, when the method getInt is called with the parameter ConfigParamKey.AGENT_MATCH_TIMEOUT then the mock should return 99.

In case you were wondering how this all happens, generics are playing an important role - thus the reason why it is only available on jdk5+

As in EasyMock and JMock you can verify that the method was called.

It is probably worth pointing out that Mockito tries to be less strict with its mocking than other mock frameworks. For example, the default mock you get will accept any call - and unless you specifically verify (which you can do), not calling the method will not cause a test failure.call

See the web site for more information, downloads and demos.

Tuesday, May 12, 2009

Best Practices are for people who don't know what they're doing

On my last project, I can remember occasionally reading through "best practices" of the various technologies we were using. Spring and hibernate spring to mind.

I can remember noting that we were not following a large number of the best practices. In fact, what is more interesting is that we had made those decisions without considering the so called "best practices".

However we did not make those decisions without considering all the variables. In each instance where we diverted from the best practice we did so for good reason and with our eyes open. In other words, we did not deviate from best practices because we were rebellious but because we knew what we were doing. In all cases we had a ready defense for not using the best practice.

I realised in doing this that the point of best practices is to protect the person who does not quite understand what they're doing, to make sure they don't really shoot themselves in the foot. For those people who understand the situation, best practices are useful because they provide a base to work from. If you deviate from best practices make sure you can defend your deviance.

Furthermore, I'd also like to add, that very often a so called best practice is someone's opinion. A few months ago I wrote on what I thought were hibernate "best practices". These are based on my experience and my opinion, they are my best practices not necessarily industry tried and tested best practices. So the label "best practice" is often a fairly loose term.

Best practices are for people who don't know what they're doing, but for people that do, the tried and tested ones are a good and worthy starting point that should only be deviated from for good reason.

Friday, May 08, 2009

Spring with annotations - in 2 minutes

I have just recently, today, had my first look at spring with annotations. Up until now I have always had to use spring on VM 1.4 so was unable to take advantage of annotations.

Suffice to say, it is awesome!

Now I know for a lot of you, this might be old news, but it wasn't for me.

So you remember the old xml based spring configuration...

<bean id="serviceLayer" class="za.co.bbd.ct.ServiceLayer">
<property name="businessObject" ref="businessObject">
<property name="xmlConfigured" ref="xmlConfiguredX">
</property>


When using annotations, no nasty xml is required.
@Component
public class ServiceLayer {

private IBusinessObject businessObject;
private IXmlConfigured xmlConfigured;

@Resource(name = "businessObject")
public void setBusinessObject(IBusinessObject businessObject) {
this.businessObject = businessObject;
}

@Resource(name = "xmlConfiguredX")
public void setXmlConfigured(IXmlConfigured xmlConfigured) {
this.xmlConfigured = xmlConfigured;
}
}
Then in your spring xml file the following is required. The good thing is that you can mix annotation and xml based configurations seamlessly.

<!-- tell spring to use annotation based congfigurations -->
<context:annotation-config />


<!-- tell spring where to find the beans -->
<context:component-scan base-package="za.co.bbd.ct" />

The default name for the bean is the class name without the package name in camel case, iow that "businessObject" class has this as its annotation:
@Component
public class BusinessObject implements IBusinessObject {

}
And if you'd rather not specify the name of the reference and just match by type:

@Autowired
public void setBusinessObject(IBusinessObject businessObject) {
this.businessObject = businessObject;
}

You can mix xml and annotation based configurations. The definition for xmlConfiguredX is also in the xml...
On a project I was on we used xdoclet to circumvent the lack of annotations (project was on 1.4). We had 100K's worth of generated xml spring configuration files. Annotations would have been so much better!

Tuesday, May 05, 2009

You don't know what you don't know...

When I started on my last project, a very large enterprise application I did not know too much. I had not done enterprise programming before, I had not used web services nor had I used hibernate, all of which were used to the fullest on the project.

When I arrived, we spent six weeks finding out what challenges lay ahead, where we would have problems and on their solutions...

Turned out that zero of what we did during that time was useful.

Problem was, we did not know what we did not know. Sounds like a redundant statement but it's not. IOW we did not know where the holes in our knowledge was. We did not know web services enough to realise that we were going to have problems interfacing via web services between dotnet and Websphere. We did not know hibernate enough to know that using inheritance and putting sub types into collection was going to be problematic. We did not know that we would have to work very hard figuring out the issues with JNDI and session beans.

We wasted a lot of time because of this. We should have got someone in, not to help us with the problems, but simply to tell us where the problems were going to be. We had the ability to solve the problems, we proved that as we solved them, what we didn't have was the knowledge to know where the problems were going to be.