What a great example Tilly! This really got my imagination going. When I first looked at your line of code:
print join ",", map { &{$field_info{$_}{format}}($deal) } @fields;

I had no idea where to begin. I couldn't see anything wrong at first. Thankfully, you're post, and the subject at hand, gave enough information that I could infer/guess what the other data structures might look like. In order to optimize your code, I had to imagine & construct the code that wraps around it, in order to simulate it's environment.

After doing some simple code, I set to look at optimizations. Right away nothing jumped out at me. I thought about hash slices, not using map, using the arrow operator, replacing join with $, and more; some of them worked, others didn't.

Then, I remembered that we are looping over a set of deals. So I made an @deals array, and started to loop over it. Then I saw it. The map was taking the @fields, and was dereferencing the subref's each time through the @deals loop. Same thing each time through. Now, assuming that @fields is not modified in the loop, we can factor it out, and do it a single time outside of the @deals loop.

There are more optimizations I could make to my code, but I didn't want to stray too far from attempting to optimize Tilly's code, and loose the point of the excercise.

Anyhow, this is what I came up with:
#!/usr/bin/perl -w use strict; #I am sure there are more fields than this my @fields = qw(a b); #Subroutines that return a value. I imagine #you had alot more processing in here, but #this is all make-believe =) my %field_info = ( a => { format => sub {return $_[0]->{deep}{inside}{a}} }, b => { format => sub {return $_[0]->{deep}{inside}{b}} }, ); #Had to simulate a reasonable amount of data, that could #potentially cause a slowdown #Let's make @ deals my @deals; for(my $i = 0; $i < 10000; $i++) { push @deals, { deep => { inside => { a => "a[$i]", b => "b[$i]"} } } +; } #Force commas to be the field seperator inside #print(), so we can drop the join(), and pass an array #to print, rather than one long "joined" string - it should be faster local $, = ','; #Set the output record seperator, so that each call to #print tags on a "\n" after printing out the $deal local $\ = "\n"; #Dereference the subroutines, so that we aren't doing a hash traversal #each time through the @deals loop AND the map. my @dereferenced_subs = map { $_->{format} } @field_info{ @fields }; #Print out each $deal foreach my $deal (@deals) { print map { $_->($deal) } @dereferenced_subs; }

How's that, did I miss anything?

Update: I found one optimization, although it could be at the expense of readability. The part where I dereference the subs before going into a loop, I changed to a hash slice to improve the speed of the hash lookup, if there was alot of fields this could make a larger difference. Also, I added a \n after each print, so that the information could be pretty printed.


In reply to Re: Re (tilly) 3: How to pass a variable to function selected from a hash by dkubb
in thread How to pass a variable to function selected from a hash by cat2014

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.