http://www.perlmonks.org?node_id=810388

SBECK has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to optimize Date::Manip where I've started to use named capture buffers (which I REALLY like), and I end up with something like the following:

     $string =~ $re;
     ($h,$mn,$s) = ($+{'h'},$+{'mn'},$+{'s'});

If I run a test case with 10,000 strings, profiling it shows that I call Tie::Hash::NamedCapture::FETCH 30,000 times at a significant time cost.

I'd like to optimize this somehow (but I'm not willing to give up named buffers). Ideally, I'd like to be able to do something like:

     %tmp = %+;
and copy out the entire hash with a single call, or something like:
     ($h,$mn,$s) = Tie::Hash::NamedCapture::FETCH('h','mn','s')
(which I realize doesn't work) so that I can reduce the problem to one call instead of 3.

Any suggestions on how this might be done?

UPDATE: Based on some of the comments, I want to clarify a couple things. First, I'm not willing to go back to numbered matches. The example I included here is VERY simple, and doesn't illustrate how much nicer a complicated regexp can be when using named buffers... but they are, and I'll take the named buffers (with the ease of maintainability that they bring) over the speed of numbered matches.

I realize that, in the example above, I'm forced to have 3 FETCH'es... I was just looking for a way to make them as optimal as possible, and if I could get an entire hash, as opposed to getting it one key at a time, the FETCH'es could all be done in the Tie::Hash::NamedCapture module (which is basically written in c with a simple perl wrapper) so it should be significantly faster. Unfortunaately, this doesn't seem to be possible.

What's left then is a call for any suggestions to optimize things within the constraint of using named buffers. One of the suggestions (using hash slices) resulted in a significant speedup (though not so much as I would expect if I could reduce the number of FETCHes), probably due to a perl optimization that I wasn't aware of, so the code now reads:

     ($h,$mn,$s) = @+{qw(h mn s)};

Thanks for all the comments and suggestions!