perlish way for ( 0 .. $n) , but downcounting

H

hofer

Hi,

I know I can live without it or with a self written iterator
or . . . , but would still like to know
other perlish ways


creating an array with numbers from 0 to 9 i would use
@a = (0...9);
for the reverse
@a = reverse(0..9);

cycling trough 0 to n (n verly large)
I'd do
$n=100000;
foreach $v (0..$n){ dowith($v) }
# If I understood well the (0..$n) would NOT create a list, but act as
iterator

for the reverse I'd hesitate to use reverse() as it creates probably
the entire list first
so I'd do either
foreach $v_up (0..$n) { $v_down = $n-$v; dowith($v); }

or foreach( $v=$n;$v>=0;$v--){ dowith($v); }



Does anybody have a 'nicer' way ?
 
J

Justin C

Hi,

I know I can live without it or with a self written iterator
or . . . , but would still like to know
other perlish ways


creating an array with numbers from 0 to 9 i would use
@a = (0...9);
for the reverse
@a = reverse(0..9);

cycling trough 0 to n (n verly large)
I'd do
$n=100000;
foreach $v (0..$n){ dowith($v) }
# If I understood well the (0..$n) would NOT create a list, but act as
iterator

[snip]

Not pretty, but works without warnings:

my $i = 1000

for ( -$i .. 0 ) {
print "$i\n";
$i--;
}

Justin.
 
W

Willem

Justin C wrote:
) Not pretty, but works without warnings:
)
) my $i = 1000
)
) for ( -$i .. 0 ) {
) print "$i\n";
) $i--;
) }

Why not go all the way then:

for (-1000 .. 0) { dowith(-$_) }


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
J

Jim Gibson

hofer said:
Hi,

I know I can live without it or with a self written iterator
or . . . , but would still like to know
other perlish ways


creating an array with numbers from 0 to 9 i would use
@a = (0...9);
for the reverse
@a = reverse(0..9);

cycling trough 0 to n (n verly large)
I'd do
$n=100000;
foreach $v (0..$n){ dowith($v) }
# If I understood well the (0..$n) would NOT create a list, but act as
iterator

for the reverse I'd hesitate to use reverse() as it creates probably
the entire list first
so I'd do either
foreach $v_up (0..$n) { $v_down = $n-$v; dowith($v); }

or foreach( $v=$n;$v>=0;$v--){ dowith($v); }



Does anybody have a 'nicer' way ?

Not any nicer, but different:

my $v = $n;
while( $v-- >= 0 ) {
dowith($v);
}
 
M

Michael Carman

Eric said:
Appending C<print scalar @x> in each case is left as an exercise for
courious reader (BTW, how to say that abreviated?)

print 0+@x;

-mjc
 
X

xhoster

Eric Pozharski said:
Don't guess, benchmark first!

But benchmark something that makes sense. None of the benchmarks
you posted make any sense in this context.

You need to use an example large enough to actually make a noticable dent
in memory, and you need to use the construct in question, which was
the range operators used directly in a foreach, with or without a reverse,
not a array being created first and then used in a foreach.

perl -le 'foreach (1..1e6) {}; print +(`ps -p $$ -o rss `)[1];'
1340

perl -le 'foreach (reverse 1..1e6) {}; print +(`ps -p $$ -o rss `)[1];'
72072

Yes, the reverse does build the whole list first.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
E

Eric Pozharski

But benchmark something that makes sense. None of the benchmarks you
posted make any sense in this context.

Yes, I've seen the light. My fault. I was misguided by
C said:
You need to use an example large enough to actually make a noticable
dent in memory, and you need to use the construct in question, which
was the range operators used directly in a foreach, with or without a
reverse, not a array being created first and then used in a foreach.

I should slightly disagree with that. The impact was noticable enough
comparing to void (it was at the bottom).

However, I've made some experiments yet. And found that if a list would
have been created explicitly, then C<foreach (reverse @l)> doesn't
create reversed copy.

*SKIP*
perl -le 'foreach (reverse 1..1e6) {}; print +(`ps -p $$ -o rss `)[1];'
72072

I've got 11K pages (44Kb) for that. 64bit? Then, I think, I've lost
that ball. Pity on me.

*CUT*
 
B

Ben Morrow

Quoth Eric Pozharski said:
However, I've made some experiments yet. And found that if a list would
have been created explicitly, then C<foreach (reverse @l)> doesn't
create reversed copy.

That is correct. Examining the code (pp_enteriter in pp_ctl.c) shows
that

1. if the argument to for() is just a range, it iterates without
creating the whole range;

2. if the argument is reverse(LIST), it expands LIST and then
iterates over it backwards;

3. otherwise, it expands the whole list.

Smells like an opportunity for a minor optimization patch... :)

Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top