Does Perl micro-optimize?

R

rihad

Hello there,

Say we have a $hash:

if ($hash{'A-String-Of-Any-Length'} eq 'foo') { ... }
else if ($hash{'A-String-Of-Any-Length'} eq 'bar') { ... }

Would Perl notice that hash lookup needs to be resolved only once, and
optimize further accesses? Or does one need to explicitly use a $tmp
for that?

Thanks.
 
M

Mirco Wahab

rihad said:
Hello there,

Say we have a $hash:

if ($hash{'A-String-Of-Any-Length'} eq 'foo') { ... }
else if ($hash{'A-String-Of-Any-Length'} eq 'bar') { ... }

Would Perl notice that hash lookup needs to be resolved only once, and
optimize further accesses? Or does one need to explicitly use a $tmp
for that?

Perl5 does not, you can check that out for yourself
by the following snippet:

my %hash = ('A_String_Of_Any_Length', 'FUD', map +(rand,rand),1..1000 );

1: if( $hash{A_String_Of_Any_Length} eq 'foo') {
print "do a lot of thinngs\n"
}
2: elsif( $hash{A_String_Of_Any_Length} eq 'bar') {
print "do not so simple things\n"
}
else {
print "do nothing\n"
}


if viewed by perl -MO=Bblock rihad.pl,
it shows both hash lookups:
...
OP (0x1838050) padhv [1]
1: SVOP (0x1838030) const [14] PV (0x1969814) "A_String_Of_Any_Length"
BINOP (0x183800c) helem
SVOP (0x1837fec) const [15] PV (0x196982c) "foo"
BINOP (0x1837fc8) seq

LOGOP (0x1837b40) cond_expr
OP (0x1837f08) pushmark
SVOP (0x1837f48) const [16] PV (0x1969820) "do a lot of thinngs\n"
LISTOP (0x1837f24) print

OP (0x1837e8c) padhv [1]
2: SVOP (0x1837e6c) const [17] PV (0x1969838) "A_String_Of_Any_Length"
BINOP (0x1837e48) helem
SVOP (0x1837e28) const [18] PV (0x1969850) "bar"
BINOP (0x1837e04) seq

LOGOP (0x1837b84) cond_expr
...

Regards

M.
 
B

Ben Morrow

Quoth rihad said:
Hello there,

Say we have a $hash:

if ($hash{'A-String-Of-Any-Length'} eq 'foo') { ... }
else if ($hash{'A-String-Of-Any-Length'} eq 'bar') { ... }

Would Perl notice that hash lookup needs to be resolved only once, and
optimize further accesses?
Nope.

Or does one need to explicitly use a $tmp for that?

Yup. Note that under some circumstances

my $tmp = $hash{foo};

can be slower than redoing the lookup, notably if $hash{foo} contains a
long string that must be copied. This can be got around with refs, but
that's messy. As ever, profile before you start thinking about
optimizing.

Note also that perl couldn't possibly perform this optimization, as it
would break tied hashes, or, at any rate, make the semantics highly
unreliable.

Ben
 
X

xhoster

rihad said:
Hello there,

Say we have a $hash:

if ($hash{'A-String-Of-Any-Length'} eq 'foo') { ... }
else if ($hash{'A-String-Of-Any-Length'} eq 'bar') { ... }

Perl doesn't have an "else if". It has "elsif"
Would Perl notice that hash lookup needs to be resolved only once, and
optimize further accesses?

I don't think so, but if it did do this kind of thing ever, it would
probably vary a lot from situation to situation and version to version.
And imagine the chaos this could cause for tied hashes.

If the look-up string were in a variable, I know that in some situations
and with some versions, the hashed integer of the (potentially very large)
string can be stored in the SV rather than needing to be recomputed. I
don't know what happens with literals.
Or does one need to explicitly use a $tmp
for that?

If one wants the lookup not to be done twice, then you would need to use
a temp variable. It seems that this is at least as likely to make things
slower as faster, though.

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

Michele Dondi

if ($hash{'A-String-Of-Any-Length'} eq 'foo') { ... }
else if ($hash{'A-String-Of-Any-Length'} eq 'bar') { ... }

If you have many such chained elsif's, then you *may* want to go the
road of HoH. I seldom if ever use explicit elsif's.
Would Perl notice that hash lookup needs to be resolved only once, and
optimize further accesses? Or does one need to explicitly use a $tmp
for that?

Sometimes I like to exploit C<for>'s aliasing properties for this
kinda things. Such use is occasionally controversial.


Michele
 
B

Ben Morrow

Quoth Tad McClellan said:
Because you told it to, via an assignment operator.


The code above is doing a write (to the $tmp variable).

There is no good reason why perl couldn't copy-on-write the scalar: that
is, make a new SV that points at the same string buffer until one of
them is modified. There is some support for this in 5.9.x, but I don't
think it's ready to be used yet (?).

Ben
 
R

rihad

There is some support for this in 5.9.x, but I don't
think it's ready to be used yet (?).

Noo, you've got to be kidding... At least subroutine arguments are
always passed by reference in Perl (which is good for speed, but bad
if you unintentionally modify them).

On a side note, and I won't be the first one to say this: Perl is
difficult. Too many special cases. Or maybe I have this impression
because Programming Perl by Larry Wall is very hard reading.
 
M

Mirco Wahab

rihad said:
Noo, you've got to be kidding... At least subroutine arguments are
always passed by reference in Perl (which is good for speed, but bad
if you unintentionally modify them).

In perl, only SV's (pointers to scalar values) or RV's (pointers
to those SV's, to Arrays, Hashes or whatever) are passed into
subroutines. There are "idiomatic expressions" for taking the
value they point to out into (copies) variables,
like: my ($var1, $var2) = @_
On a side note, and I won't be the first one to say this: Perl is
difficult. Too many special cases. Or maybe I have this impression
because Programming Perl by Larry Wall is very hard reading.

Thats true in my opinion, The "LLama Book"
(http://www.oreilly.com/catalog/lperl3/) is
much better for you if you jump into Perl
from somewhere else. The "Camel Book",
(http://www.oreilly.com/catalog/pperl3/index.html)
which is the book you mentioned, will be most
valuable if you are at least somehow "intermediate".

Regards

M.
 
M

Michele Dondi

Noo, you've got to be kidding... At least subroutine arguments are
always passed by reference in Perl (which is good for speed, but bad
if you unintentionally modify them).

Nooo, arguments passing is known to be terribly inefficient in Perl.
Ask Ilya!!
On a side note, and I won't be the first one to say this: Perl is
difficult. Too many special cases. Or maybe I have this impression

Yes it is, and yes there are. But you're not required to know them all
from scratch.

However, if you're patient enough, Perl 6 will be an even more complex
language whose complexity will be built by the complex interaction
between simpler pieces, in a consistent and orthogonal manner, with no
special cases.


Michele
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top