Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

using function output ananymous array vs. named array in foreach

by ISAI student (Scribe)
on Dec 26, 2012 at 10:42 UTC ( [id://1010354]=perlquestion: print w/replies, xml ) Need Help??

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

I am asking this performance and memory footprint-wise. While I can experiment on my own, I'd rather have an analytical answer rather than empiric

The Two packs of code do the same action. Should there be any perforance gap (memory and/or execution time) chunk 1:

my @lines=foo('bar'); foreach my $line (@lines) { $a.=chomp $line ; $b*= getVa($line);# a parsing function }
chunk 2:
foreach my $line ( foo('bar') ) { $a.=chomp $line ; $b*= getVa($line);#a parsing function }
Assume that @lines is not used anywhere else in the scope of code. I would assume that memory footprintwise, 2nd chunk should be no larger than chunk 1, unless the garbage collection does not work in the wasy I expect it to. I am not sure how should the performance scale. Thanks

Replies are listed 'Best First'.
Re: using function output ananymous array vs. named array in foreach
by BrowserUk (Patriarch) on Dec 26, 2012 at 11:48 UTC

    Neither snippet will do what you think it will do. chomp returns whatever is chomped off, not the line, so $a, will end up being a bunch of delimiters.

    In terms of performance, there will be little to choose between them; they'll both be quite slow.

    In terms of memory, the first will hang on to the memory used by @lines until you explicitly clean it.

    You might find this does what you are after more efficiently:

    my @lines = foo( 'bar' ); chomp @lines; my $a = join '', @lines; my $b; $b *= getVa( $_ ) for @lines; undef @lines;

    As for scaling: if fun() can returns very large numbers of lines, building an array inside the function and then returning that array as a list will scale badly.

    You could either pass a reference to the array into foo() and having it populate it; or return a reference to the array constructed internally; this avoiding the construction of the list and the copying of the array.

    But better yet would be to move the chomping, concatenation and parsing inside the loop where the lines are read or generated, and return the concatenated string and the accumulated total; thus avoiding the construction of the array completely:

    sub foo{ my $bar = shift; my( $a, $b ); ... while( my$line = getLine() ) { chomp $line; $a .= line; $b *= getVa( $line ) } return $a, $b; } my( $a, $b ) = foo( 'bar' );

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      chomp returns whatever is chomped off, not the line, so $a, will end up being a bunch of delimiters.

      Well, actually chomp() returns the number of "characters" that were chomped - not the delimiters. So the OP's code is not going to work or I will admit that I am having a hard time understanding what this thing it supposed to do.

      A short demo of chomp() on my Windows machine:

      #!usr/bin/perl -w use strict; #chomp demo #running on Windows XP 32 bit... # chomp... "It removes any line ending that corresponds # to the current value of $/ (also known as # $INPUT_RECORD_SEPARATOR in the English module)." # # chomp() returns the total number of "characters" removed. # The "number of characters" depends.... my $count; print "Count\t Text\n"; my $x ="blah...with CRLF (Windows)\n"; $count = chomp ($x); print "$count \t\t $x\n"; print "setting \$/ to \\r\n"; $/ = "\r"; my $y ="blah...with CR (like Old Mac)\r"; $count = chomp ($y); print "$count \t $y\n"; print "This won't work...An \"extra new line\" remains...\n"; my $z ="blah again with CRLF (Windows)\n"; $count = chomp ($z); print "$count \t\t $z\n"; print "set \$/ back to \\n \n"; $/ = "\n"; $z ="blah again with CRLF (Windows) but 2 CRLF's\n\n"; $count = chomp ($z); print "only one of the \\n's is chomped\n"; print "$count \t\t $z\n"; print "end of demo\n"; __END__ Count Text 1 blah...with CRLF (Windows) setting $/ to \r 1 blah...with CR (like Old Mac) This won't work...An "extra new line" remains... 0 blah again with CRLF (Windows) set $/ back to \n only one of the \n's is chomped 1 blah again with CRLF (Windows) but 2 CRLF's end of demo
        actually chomp() returns the number of "characters" that were chomped - not the delimiters.

        You're right of course. (But your over elaborate demonstration added nothing to the simple statement of fact.)

        I remember discovering early on that the return from chomp wasn't useful and I've never concerned myself with what non-useful thing it actually returned ever since.

        So the OP's code is not going to work...

        That was the point I was making when I said: "Neither snippet will do what you think it will do.".


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
      You are probably right, but I can't touch foo at the moment... It stands for a number of objects' methods that I cannot change. I am given this deck of cards, and deal with it... I guess that for the sake of simplicity, brevity (and less duration of memory footprint), I'll use the anonymous array method.
        for the sake of simplicity, brevity (and less duration of memory footprint), I'll use the anonymous array method.

        Neither of your OP snippets uses an anonymous array.

        Your function returns a list, which you either: assign to an array which you then process using for; or you process the list directly with for.

        But yes, there is no purpose to assigning to the array, unless you needed to retain the returned values beyond the loop.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: using function output ananymous array vs. named array in foreach
by Anonymous Monk on Dec 26, 2012 at 11:12 UTC
    There is no analytical answer to be had, one may use more memory, or both may use the same memory, and it may depend on perl version, the only way to know is to test, or read the source code -- see Mini-Tutorial: Perl's Memory Management

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1010354]
Approved by NetWallah
Front-paged by NetWallah
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (7)
As of 2024-04-23 10:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found