The Code Crunch

Name:
Location: Orange, CA, United States

Thursday, August 31, 2006

C++ vs. Java

Over a mediocre meal I recently had a vehement coversation with another programmer about the best uses for the C++ languages vs. Java.

After we'd gotten done cracking jokes about how "Java is great if you want to load 250 megs into RAM just to print 'hello world'", and "C++ is perfect for people who have bosses that don't mind them spending all day writing string and memory handling objects instead of application code", we covered the various pros and cons of the languages.

Here's the Cliff Notes:

Java:

Use it when development time is more important than application performance. Suited for large complex projects since the language and associated APIs lend themselves very well to managing this complexity, and allow for much easer porting (little to no per-platform code). Inferior system-level integration (i.e. you can't easily get down and dirty call OS-specific calls, provide native (C) callbacks, etc.) as compared to writing in C or C++, plus system-level code often has performance requirements that make Java prohibitive.

C++:

While C++ with its language-level bells and whistles like operator overloading and multiple inheritance can be built up into a much higher level and object-oriented environment than writing straight C - it still doesn't cut the mustard when you are talking about large enterprise applications. C++ has significant performance advantages, so it's suited for system level work, as well as smaller programs in which the developers can more easily cope with the added complexity that comes from having to manage memory, be careful with pointers and casting, etc.


Alas, we all must select our weapons before each battle (use the right language for the project at hand).

Code Coverage

Ah yes, code coverage. (The amount of code that actually gets executed when you run or test your program.)

I friend of mine describe his experience with code coverage while working for IBM:

In one of their now-long-gone projects that didn't imploy code coverage, they were planning to implement it, and were taking guesses as to what percentage of the code was covered. They guessed maybe 70%, okay maybe 60% if we're really bad.

And the figure?
18%

Yes my friends, that means 82 out of every 100 lines of code was not being executed by the path through the program that was run by their tests. Can you say: BUGS!

The moral of the story: Check your code coverage, there's open source software to do it, and you'll come away with better code and a one-up on the competition.

Why Unit Test?

Unit testing is one of those things that it's easy to live without - before you've lived with it. A programmer that I've known in passing for many years who writes C# code for a medium-sized database software company recently told me that they have no unit testing at all for their main line product.

I was shocked. Of course this programmer had wanted to do this for a while, and had even had another junior programmer assigned to the task for a short time, before he got taken off to do some other "more important" part of the project. Uh ho.

Well, I wish I had some figures to give you, since I'm sure they would be quite revealing, but lacking that I'll have to get by with just a bit of logic:

How much time do you spend debugging code v.s. writing it? Especially as your project grows. As it grows it gets worse and worse, even the smallest changes require significant debugging, because of the effects that they have on all of the other parts of the system.

This is where unit testing shines. Most people who don't unit test claim that the testing itself takes too much time. And, at the beginning of a project, this is true. But what this viewpoint fails to consider is that as the project grows so does the potential for introducing bugs - simply beacuse there's more code running. And after you've written several thousand lines of code or so, the tide starts to turn, and all of the little bugs start to crop their little heads up - the bugs that would have been handled by unit testing.

So I'd say one of the key factors to consider when looking at how much unit testing should be involved in a project is the project's size/lifespan. If it's fairly complicated, and is going to be around for a bit - you definitely want to unit test.

Don't forget about design in the code crunch

It's always an important thing to be working from a sufficiently complete design when you are coding. Afterall, code without proper design essentially just makes spaghetti.

After going through a number of projects, I've worked out for myself and my team some specific things to do that go a long way in contributing to proper design:

1. Figure out exactly what the thing is supposed to do. In many, many cases HUGE problems can be caused because what the program is supposed to do was never nailed down. Figure it out, and write it down, as detailed as is useful.
2. Do a class diagram or several. If you don't understand how your design fits into objects, you're toast. Take the time to diagram it out, get as detailed as possible. Sometimes when you do this you hit a wall after a bit where there are simply too many unknowns to proceed and make anything useful. At that point I usually go and pound out some prototype code, then return to the class diagram with my new-found knowledge.
3. When you start writing, begin by writing the interfaces. Define how the parts of the system interact with each other. Keep the implementations stubbed, focus on the interaction. This way you iron out the structure points while the actual implementation code is lightweight. After, the bulk of your time is spent (a) working out the correct design and structure and (b) writing all of the intense crazy code that is buried deep inside some methods in a very implementation-specific classes. So the key is to get the design by work right by focusing on getting all of the interfaces talking to each other before you go and writing a bunch of gnarly implementation specific stuff that you have to rewrite when you do design changes.
4. Unit test! Even when you think it's a pain in the arse, unit testing usually saves you time in the long run (the only valid exceptions I can see are (a) if your design is such utter tripe that it's parts absolutely cannot be unit tested without dramatic changes, or (b) if you are writing a part that is very simple and the probability that it will be messed up is very low - but then again, it's easy to misestimate).
5. Document. Some poor sod is going to have to look at your code again (especially if you did a good design!) And of course the scary thing is: It's probably going to be you! So document your stuff before you find yourself asking the rhetorical question "What the heck was this guy thinking when he wrote this?"

I'll post some more stuff as I come up with it.