It's interesting how, when a software program grows, it may not evolve exactly as it should.
I was working on my anti-spam program two nights ago, and I noticed it had this growth problem. When I first starting creating the program it was supposed to mark email messages w/ varying levels of suspicion, kind of a Bayesian algorithm. But, in practice, I found that this wan't really necessary; a message was either spam, or it wasn't.
However, as my program grew I ended up leaving code in it like this:
incrementSpamRatingBasedOnSubjectField(message); incrementSpamRatingBasedOnFromField(message); incrementSpamRatingBasedOnContents(message); incrementSpamRatingBasedOnSubjectMisspellings(message); incrementSpamRatingBasedOnAttachments(message);
This caused each message to be evaluated five times, even if it was "rejected" in the first method/test based on the subject field.
What I realized the other night was I really wanted something more like this instead:
incrementSpamRatingBasedOnSubjectField(message); if (!message.markedForDeletion()) incrementSpamRatingBasedOnFromField(message); if (!message.markedForDeletion()) incrementSpamRatingBasedOnContents(message); if (!message.markedForDeletion()) incrementSpamRatingBasedOnSubjectMisspellings(message); if (!message.markedForDeletion()) incrementSpamRatingBasedOnAttachments(message);
Since making this change, the anti-spam program has obviously been running much, much faster. As soon as a message is marked for deletion, it never visits the other methods.
I know that I can clean this code up even more, but the interesting part for me here was that when the model/paradigm for the code was changed, it got lost in translation, and I never refactored other sections of the code to match the new model. In this case, this made the anit-spam program run much slower than needed, until I caught this problem the other night.