Archive for May, 2009

Site back online…

Wednesday, May 27th, 2009

… and hopefully most of the content is here somewhere.  I’ll be updating it over the next week to get everything back in order.  I’ll also be working on recreating my template one more time for Wordpress this time.

I’ll write more about my switch over tomorrow.

Working on a new site

Thursday, May 21st, 2009

I will be quiet through Memorial Day as I complete work on a new version of this site.  I hope to get all the content transferred over sometime this weekend, so I can switch over and start up on the new site first thing next week.

Reading Code without brackets

Monday, May 18th, 2009

Quick question, what is wrong with the following code?

bool result = false;
if (test1) {
  if (subtest1) {
    DoSomething();
  } else
    DoSomethingElse();
  result = FinalMethod();
} else if (test2) {
  result = GetSecondResult();
}
return result;

Stumped?  What if I told you that FinalMethod should only be called if “subtest1” is false?

I have changed the names and circumstances to protect the innocent, but the facts of the error remains the same as one i just encountered in a code review.  Of course, even knowing that little tidbit of information, it still took me a couple of minutes to see the error (Fortunately my spidey sense was tingling, so I knew *something* was wrong…)  The first time I read the code, this is what I saw (I reformatted to make the misperception clear, but the formatting was in reality the same as above):

bool result = false;
if (test1) {
  if (subtest1) {
    DoSomething();
  } else {
    DoSomethingElse();
    result = FinalMethod();
  } else if (test2) {
    result = GetSecondResult();
  }
}
return result;

Of course, that is a nonsensical statement, but that is how my brain interpreted the block.  Since the code was missing the brackets around the else statement, my brain simply supplied the expected syntax, regardless of its validity.  Given that the error was an introduced error, it is safe to assume the original developer’s brain did much the same thing, since there was even a comment to the effect that if subtest1 failed it would return the result of FinalMethod().

So how can we prevent these types of errors?  If our brains are actively working against us, then we need to work to give our brain what it wants:

bool result = false;
if (test1) {
  if (subtest1) {
    DoSomething();
  } else {
    DoSomethingElse();
    result = FinalMethod();
  }
} else if (test2) {
  result = GetSecondResult();
}
return result;

Now there is no need for our brain to supply the missing brackets, since they are explicit.  In addition, if we had originally used those brackets, it would have been immediately clear to anyone reading the code that the call to FinalMethod was occurring outside the else block, making the error much easier to detect, and much more unlikely to enter the codebase.

Casting Performance

Tuesday, May 12th, 2009

The system that I am currently working on depends a lot on casting an object to an interface to see if it implements that interface.  If it does, the system will take one action, if not, it will take a different action.  Because of this, casting performance is very important to the overall performance of the software.

As far as I am aware, there are 4 ways in C# to test if a given instance of an object implements an interface (without knowing the exact type of the instance).

1. “as” cast after an “is” check:

if (castingObject is StringBuilder)
{
  StringBuilder testBuilder = castingObject as StringBuilder;
  // do stuff
}
else
{
  // do other stuff
}

2. “as” cast with a null check:

StringBuilder testBuilder = castingObject as StringBuilder;
if (null != testBuilder)
{
  // Do stuff 
}
else
{
  // Do other stuff
}

3. Explicit cast after an “is” check:

if (castingObject is StringBuilder)
{
  StringBuilder testBuilder = (StringBuilder)castingObject;
  // Do Stuff
}
else
{
  // Do Other Stuff
}

4. Explicit cast with InvalidCastException:

try
{
  StringBuilder testBuilder = (StringBuilder)castingObject;
  // Do Stuff
}
catch(InvalidCastException)
{
  // Do other stuff.
}

Method #4 should clearly be the worst performing option if you expect any number of the casts to fail (since throwing an exception is very expensive in .NET).  So which of the three remaining methods would result in the best performance?  Well, the only way to know for sure is to measure it, so that’s what I did.

As Cast with Is check: 0.0082533 seconds.

As Cast with Null check: 0.0077226 seconds.

Explicit Cast with Is check: 0.008119 seconds.

Explicit Cast with No check: 448.7026034 seconds.

Judging from these results, doing an “as” cast followed by a null check is the fastest way to test if an object instance is of a certain type.  Of course, there is not enough of a difference between any of the first three methods to make me redo any existing code, and I certainly wouldn’t sacrifice readability/maintainability just to grab 5 milliseconds or so over 200,000 casts.

If you are curious I ran the casts inside a 100,000 iteration loop, with one “successful” cast and one “failed” cast, for a 50% success rate.  A more clever test would take into account the actual expected failure rate of the casts and use that to measure the performance, but this was just a question of curiosity for me – as I mentioned the possible improvements are too small for me to worry about as long as I avoid the explicit cast with no checks.

How to lose a customer, in 1 easy step

Monday, May 11th, 2009

Finding new customers is hard.  First, you have to identify the people who are interested in what you are selling.  Then you have to find a way to meet those people so you can tell them about what you are selling.  Then you have to convince them that they want what you are selling, and if you manage to do all that, you still have to agree to a price for everything.

Doing that takes time, money, and a whole lot of effort and patience.

On the other hand, if someone is already a customer of yours, things become much easier.  You already know who they are and what they want.  They already know you and (hopefully) trust you and want to purchase your product or service.  So all that’s left is to agree on a price – which should be easy because they already have some expectation based on their previous purchase.

Given that keeping an existing customer is so much easier than finding a new one, you would think that companies would work hard to make sure that their existing customers stay customers.

Sometimes companies keep customers (either intentionally or not) through “lock-in” – they make it so difficult to switch to a competitor that it isn’t worth the cost.  This is essentially why Microsoft dominates the business world.  The cost of switching is too high for most companies – they simply can’t do what they need to do on other platforms (or they don’t know how).  Comcast keeps its customers despite horrible services, prices, and policies because in most cases they are the only option for cable or high speed internet.

So how do you keep a customer if there are low barriers to switching or lots of competition?

You can try to create “brand loyalty”.  By creating a community around the product or company, you can convince people to keep coming back.  This is (more or less) what Apple relies on.  You can also create loyalty through exceptional customer service.  HP support managed this when they promptly and efficiently fixed my out-of-warranty laptop for free.  REI does this through their simple and generous return policy (if it breaks or you don’t like it – return it).

If none of these options are possible, you are left to compete on price, and if you are competing on price you better price yourself accordingly.

Take for example, my webhosting provider.  I use webhost4life.  They have been OK – they have had several service outages and issues with my site, but on the whole I’ve been satisfied with their service over the past year.  Being inherently lazy, I decided to renew my plan, and look into adding a second site for my photography work.  Imagine my shock when I discover that they wanted to charge me for the privilege of renewing my plan.  Since all the work in setting up the hosting plan had already been done, essentially they are trying to charge me for taking my money.  To add insult to injury, if you sign up for a new account with them, they will not charge a setup fee – so it is cheaper to be a new customer than an existing one, yet somehow they expect me to feel some compulsion to continue purchasing their service.

Not going to happen.

They are competing on price, and there is a lot of competition out there.  The cost of switching is roughly one hours worth of work – most of which doesn’t even require my attention (uploading and downloading the site).  They are a company that didn’t realize how they were competing, and as a result lost customer.

Good Time to be a Developer

Wednesday, May 6th, 2009

According to the IEEE, the number of software developers is decreasing worldwide.  Why do I think this is a “good” thing?  Because the US Bureau of Labor Statistics projects the demand for software developers to grow by over 30 percent, one of the fastest projected growth rates.

So with a shrinking labor pool and increased demand, the job prospects for software developers looks good (at least in the longer term).  Hopefully that means that some of the younger generation coming up through school will see this and view the field as a viable career option, reversing the downward trend of enrollment in Computer Science (and Engineering).  There is some evidence this may be occurring, as for the first time in almost 6 years, enrollment in Computer Science has increased.

I’m hoping this continues, since this influx of new talent and ideas is critical to continue advancing and shaping our field in the future.

Besides, I enjoy writing software, and I’d like to continue doing it for a while…

Opening Doors

Tuesday, May 5th, 2009

Imagine that you have a pressing need to hire a top-notch software developer.  You contact all your friends and colleagues to put out the word.  You call up a couple of recruiters and put an ad on a couple of websites.  You canvas some relevant conferences.

Soon you have a pile of resumes.  Depending on your company and how much advertising you’ve done, you might have thousands of resumes.  So you sit down to run through them, rapidly discarding the vast majority until you find one with those magical three words, “Open Source Experience”.  BAM.  Search over, move on, right?

Looking around the web, it seems accepted that job seekers should participate in open-source projects because it will help them get a job.  The theory is that by participating, you make a portfolio of your work available to any prospective employer, so they can verify your technical aptitude.  It also seems to be the prevailing wisdom that only the “best of the best” participate in open-source projects (as it is supposed to be a meritocracy).

While I can’t speak to the general quality of open-source developers versus the average developer, I can speak to the value of an employer being able to look at your portfolio of work.  While I am certainly not the first person to suggest this, it bears repeating so that people do not fall into the trap of placing too much value on it.

I will not review your work on an open source project.

Having source code available bears no relevance to the hiring process.  Remember that I have thousands of resumes.  Most of the time I won’t even read the entire RESUME, much less go look at the source control history of some open-source project on the web to determine what code is yours and evaluate it. 

I am interested in your experience.  Whether you gave the code away or not generally does not matter as much as whether the code you wrote is relevant to the position I am hiring for, and I should be able to determine that from your resume.

I might check to verify that you actually committed code to the stated project.  I might even go so far as to see what parts you worked on.  But that is no different than me calling up a former employer to verify that you worked there.  By the time I do these things, I’m already interested in hiring you.  I’ve probably already interviewed you and determined you are a good fit for the position. 

If I want to see what kind of code you write, I’ll ask you to write some code as part of the interview, and if I ask you to write some code, you can bet I’ll ask the other candidates to solve the same problem.  This way I can compare and contrast everyone’s strengths and weaknesses from a common starting point.

So, essentially, my advice on whether to contribute to open-source projects is this.  If you want to contribute to open-source projects, please do so.  The networking and development skills you gain will be invaluable in finding a job.  The best way to become good at something is to practice, so learn how to read code, learn to fix bugs, develop new features, respond to complaints.  All these things are valuable skills you can gain by working on open-source projects.

Just don’t expect your open-source experience to magically open any doors for you.  Proprietary-source developers are all learning the same thing.  You still need to demonstrate all the same intangible qualities and experience that companies look for to set a candidate apart.  If you can’t even be bothered to show me why you would be a good candidate, why should I be bothered to find out if you are or not?

Performance Reviews

Monday, May 4th, 2009

Its that time of year again.  The time when employees everywhere are forced to justify their existence to management, and talk about all the great things they have done for the company.  So, in honor of the occasion (and since I’m still recovering from my whirlwind few weeks of travel), I want to point you to this commentary on performance reviews.  Even after all these years (it was first published in 1993), the accuracy of the commentary still hits home.

So, here’s to another day spent filling out useless forms and identifying “accomplishments” suitable for presenting my work in the appropriate context to upper management, and for everyone else going through the same charade, good luck.