18.6. Optimizing String Manipulation
The final step of the Soundex algorithm is padding short results with zeros, and truncating long results. What is the best
way to do this?
This is what we have so far, taken from soundex/stage2/soundex2c.py:
These are the results for soundex2c.py:
The first thing to consider is replacing that regular expression with a loop. This code is from soundex/stage4/soundex4a.py:
Is soundex4a.py faster? Yes it is:
But wait a minute. A loop to remove characters from a string? We can use a simple string method for that. Here's soundex/stage4/soundex4b.py:
Is soundex4b.py faster? That's an interesting question. It depends on the input:
The string method in soundex4b.py is faster than the loop for most names, but it's actually slightly slower than soundex4a.py in the trivial case (of a very short name). Performance optimizations aren't always uniform; tuning that makes one case
faster can sometimes make other cases slower. In this case, the majority of cases will benefit from the change, so let's
leave it at that, but the principle is an important one to remember.
Last but not least, let's examine the final two steps of the algorithm: padding short results with zeros, and truncating long
results to four characters. The code you see in soundex4b.py does just that, but it's horribly inefficient. Take a look at soundex/stage4/soundex4c.py to see why:
Why do we need a while loop to pad out the result? We know in advance that we're going to truncate the result to four characters, and we know that
we already have at least one character (the initial letter, which is passed unchanged from the original source variable). That means we can simply add three zeros to the output, then truncate it. Don't get stuck in a rut over the
exact wording of the problem; looking at the problem slightly differently can lead to a simpler solution.
How much speed do we gain in soundex4c.py by dropping the while loop? It's significant:
Finally, there is still one more thing you can do to these three lines of code to make them faster: you can combine them into
one line. Take a look at soundex/stage4/soundex4d.py:
Putting all this code on one line in soundex4d.py is barely faster than soundex4c.py:
It is also significantly less readable, and for not much performance gain. Is that worth it? I hope you have good comments.
Performance isn't everything. Your optimization efforts must always be balanced against threats to your program's readability
and maintainability.