My software development lifecycle has a mantra: correct, clear, concise, competitive. It's almost never worth optimizing code that doesn't do the right thing. Without tests, you don't know it does the right thing, or if it does things right. Without tests, you have little hope of knowing that your optimization retained correctness. If you keep clarity, concise code is always better than verbose code.
Fortunately, Parrot and Rakudo have several tests.
Yesterday's optimization was nice, but I figured there were still more possibilities for optimizations, even without adding complexity to the system.
Today's improvement was 17.53% on the NQP/Rakudo benchmark I've been using. (This benchmark is the single most expensive piece of code in all of Rakudo, and it exercises a lot of the paths that Perl 6 on Parrot will execute.)
The Class PMC (which represents classes in Parrot) has an operation called
get_string
, which returns the name of the class. When there's no
namespace associated with the class, there's little work to do; the class
simply returns its name directly. If there is a namespace associated with the
class, the code gets the name of the namespace (in an array of strings), then
joins them all together into a string.
Prior to Parrot revision 26928, it did this work on every call. Besides calling several functions, it created and returned a new string for each call. I changed this code to cache the class name, and there's an immediate performance improvement in all OO code -- even the code I optimized yesterday. That's a nice benefit.
I may be able to remove the attribute I added to the Class PMC if I can prove that the short name and the long names are always isomorphic -- that is, if there's no reason never to use a short name if there's a long name. I think that's the case, but I can't prove it yet.
Sadly, this may be the last easy performance improvement for a while. The next three hotspots look much more complex to unravel.