why are references so slow ?

D

Daniel Dünker

I have a script, with lots of deep recursion and noticed, that with the usage of references the whole programm becomes *much* slower (i noticed that in an earlier state, when i wanted to put something often used into a sub. The programm took at first less than 1 second, after i created the sub it took more than 5 seconds to complete.)
Now i am at a point where i want to use recursion, and perl says its even a deep recursion.
So, should i throw away all the parameters and just use global variables to get rid of referencing and dereferencing ?
 
B

brian d foy

Daniel said:
I have a script, with lots of deep recursion and noticed, that with the usage
of references the whole programm becomes *much* slower (i noticed that in an
earlier state, when i wanted to put something often used into a sub. The
programm took at first less than 1 second, after i created the sub it took
more than 5 seconds to complete.)
Now i am at a point where i want to use recursion, and perl says its even a
deep recursion.
So, should i throw away all the parameters and just use global variables to
get rid of referencing and dereferencing ?

Well, before you do anything, profile the application to see where the
slow parts really are. I would be surprised if it's the references, and
surprised if you haven't coded something that's an inefficient
algorithm (especially since you noted a deep recursion warning).

I talk about profiling in chapter 5, "Profiling", of Mastering Perl:

http://www252.pair.com/comdog/mastering_perl/Chapters/

Good luck :)
 
B

Brian McCauley

I have a script, with lots of deep recursion and noticed, that with the usage of
references the whole programm becomes *much* slower (i noticed that in an
earlier state, when i wanted to put something often used into a sub. The programm
took at first less than 1 second, after i created the sub it took more than 5 seconds to
complete.)

I'm not sure what this has to do with references but subroutine
calling it expensive in Perl. As are constructing and unpacking
argument lists.
Now i am at a point where i want to use recursion, and perl says its evena deep
recursion.

If you want to use recursion I don't think you can do it without
subroutines. You'd have to refactor your code to be iterative.
So, should i throw away all the parameters and just use global variables to get rid
of referencing and dereferencing ?

I think it would have been clearer if you'd given us an example but if
I've understood correctly you effectively have a bunch of variables
that you are just passing unchanged down the recursion. Yes I'd
replace these by variables that are by some definition "globals". That
is to say they are used inside a subroutine but are not passed as
arguments. There are two obvious ways to go about this...

# Original

sub foo {
my ($this,$that,$other) = @_;
# stuff using $this,$that,$other...
# ...but not changing $this or $that
foo ($this, $that, whatever);
# stuff...
}
######################################

# With closure
sub foo {
my ($this,$that,$other) = @_;
my $r;
$r = sub{
my ($other) = @_;
# stuff using $this,$that,$other...
$r->(whatever);
# stuff...
};
$r->($other);
undef $r; # break circular reference
}
####################################

# With package variables and local()

our ($this,$that);

sub r {
my ($other) = @_;
# stuff using $this,$that,$other...
$r->(whatever);
# stuff...
}

sub foo {
(local($this,$that),my ($other)) = @_;
r($other);
}
 
D

Daniel Dünker

Well, before you do anything, profile the application to see where the
slow parts really are. I would be surprised if it's the references, and
surprised if you haven't coded something that's an inefficient
algorithm (especially since you noted a deep recursion warning).

I talk about profiling in chapter 5, "Profiling", of Mastering Perl:

http://www252.pair.com/comdog/mastering_perl/Chapters/

Good luck :)

Wow thanks, that's a very interesting tool, and of course you are right, there are still lot's of inefficient things in my script, but it seems that the slowest part's are actually really referencing and dereferencing, as for example:
4455 3.53946 3.40000 133: return \%pixels;
which is the part that takes the most time.
 
M

Michele Dondi

I'm not sure what this has to do with references but subroutine
calling it expensive in Perl. As are constructing and unpacking
argument lists.


If you want to use recursion I don't think you can do it without
subroutines. You'd have to refactor your code to be iterative.

(Mostly as an aside) if the recursion can be cast in the form of tail
recursion than much hassle can be eliminated, but existing perls
unfortunately don't handle it natively so one has to take care of that
"manually" with *magic* goto()s.


Michele
 
X

xhoster

Daniel =?UTF-8?B?RMO8bmtlcg==?= said:
Wow thanks, that's a very interesting tool, and of course you are right,
there are still lot's of inefficient things in my script, but it seems
that the slowest part's are actually really referencing and
dereferencing, as for example:
4455 3.53946 3.40000 133: return \%pixels;
which is the part that takes the most time.

How do you know it is the reference, rather than the return, that is
taking the time? You could separate them into two different lines:

my $foo=\%pixels;
return $foo;

Also, I don't find Devel::SmallProf to be particularly reliable. Small
errors in its null compensation methods can lead to substantial spurious
timings.

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.
 
D

Dr.Ruud

Michele Dondi schreef:
(Mostly as an aside) if the recursion can be cast in the form of tail
recursion than much hassle can be eliminated, but existing perls
unfortunately don't handle it natively so one has to take care of that
"manually" with *magic* goto()s.

Can you show an example?
 
B

brian d foy

Wow thanks, that's a very interesting tool, and of course you are right,
there are still lot's of inefficient things in my script, but it seems that
the slowest part's are actually really referencing and dereferencing, as for
example:
4455 3.53946 3.40000 133: return \%pixels;
which is the part that takes the most time.


remember that one line of a report like that doesn't mean much devoid
of the context of everything else going on. Feel free to post more of
the report :)

also, I don't know what is going on in that subroutine, but returning a
reference, which is just a scalar, shouldn't be talking up that much
time. Can you show the subroutine?
 
G

Greg Bacon

: >Can you show an example?
:
: It's surely discussed in HOP, but I don't know if it's online yet.
: [...]

It's my recollection that Dominus had planned to include a
section on eliminating tail-calls with goto-&NAME but
abandoned the idea. (Seems like he couldn't make it work.)

Greg
 
U

Uri Guttman

GB> In article <[email protected]>,

GB> : >Can you show an example?
GB> :
GB> : It's surely discussed in HOP, but I don't know if it's online yet.
GB> : [...]

GB> It's my recollection that Dominus had planned to include a
GB> section on eliminating tail-calls with goto-&NAME but
GB> abandoned the idea. (Seems like he couldn't make it work.)

my guess is that the problem is setting up @_ is a pain. magic goto
leaves @_ to be passed to the called sub. many recursive calls will have
different @_ than they want to pass on so you have to mung @_ in some
wacky ways. surely it can be done but it will be fugly and maybe not
even efficient with the extra code needed.

for more speed i would rather unroll the recursion into a loop and use a
private stack. that is the classic way to speed up recursion which is
slow in perl due to all the sub calls. with this solution you don't have
tail recursion issues at all.

uri
 
A

all mail refused

You should use nothing BUT global variables. Throw away subroutine parameters alltogether!

Precompute all your programs and then for each situation run eithr /bin/true or /bin/false.
 
T

Ted Zlatanov

amr> Precompute all your programs and then for each situation run eithr /bin/true or /bin/false.

You might as well just write Quantum::Superpositions one-liners.

Ted
 
B

Ben Morrow

Quoth Ted Zlatanov said:
parameters alltogether!

amr> Precompute all your programs and then for each situation run eithr
/bin/true or /bin/false.

You might as well just write Quantum::Superpositions one-liners.

I'm not sure that would help... I'm fairly sure Acme::HaltingProblem
would be required as well :).

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,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top