$ perl -MO=Concise -e 'my @a';
4 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v ->3
3 <0> padav[@a:1,2] vM/LVINTRO ->4
$ perl -MO=Concise -e 'my @a = ()';
7 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v ->3
6 <2> aassign[t2] vKS ->7
- <1> ex-list lK ->4
3 <0> pushmark s ->4
- <0> stub lP ->-
- <1> ex-list lK ->6
4 <0> pushmark s ->5
5 <0> padav[@a:1,2] lRM*/LVINTRO ->6
I see the idiom:
my @foo = ();
my %foo = ();
my $foo = undef;
quite often in code made by not too experienced Perl programmers.
Seems like an easy fix with a good potential for an overal increase
in performance of Perl. A small benchmark shows that the difference
is quite significant (relatively speaking, of course).
cmpthese( -2,{
new => sub {my @a = ()},
old => sub {my @a},
} );
__END__
Rate new old
new 648871/s -- -55%
old 1447413/s 123% --
Or maybe a warning should be issued if warnings are enabled?
Liz
Only 99.95% sure... wanted to be 100% sure... ;-)
Thanks for the confirmation...
Liz
No.
Here's a patch for turning C<my $x = undef> into C<my $x>.
The array/hash case is similar, except that it needs more optree
inspection, a new ck_aassign function, and I'm tired tonight...
Index: op.c
===================================================================
--- op.c (revision 3350)
+++ op.c (working copy)
@@ -5593,6 +5593,19 @@ Perl_ck_sassign(pTHX_ OP *o)
return kid;
}
}
+ /* optimise C<my $x = undef> to C<my $x> */
+ if (kid->op_type == OP_UNDEF) {
+ OP *kkid = kid->op_sibling;
+ if (kkid && kkid->op_type == OP_PADSV
+ && (kkid->op_private & OPpLVAL_INTRO))
+ {
+ cLISTOPo->op_first = NULL;
+ kid->op_sibling = NULL;
+ op_free(o);
+ op_free(kid);
+ return kkid;
+ }
+ }
return o;
}
End.
Is this a good idea? It's just extra bloat for a case that more
experienced perl programmers wouldn't do. Especially the idea
of adding a new ck_ routine just for this seems unworthwhile.
(Though I'd always assumed that ck_null wasn't actually called and
now I see it is. Perhaps there's a good place for an optimization.)
Yes. It is a good idea.
/pkg/perl-5.8.0/lib/5.8.0$ egrep -r 'my @[a-z]+ *= *\(\)' * | wc -l
64
/pkg/perl-5.8.0/lib/site_perl$ egrep -r 'my @[a-z]+ *= *\(\)' * | wc -l
161
Personally, I _like_
my @foo = ();
because it makes it crystal clear, no doubt about it, that @foo is the
empty list.
-R
The bloat is minimal, the compile-time cost negligible, and the runtime
cost negative or zero. I'd say it is worth it.
If it lets perl programmers write clearer code without worrying about
nano-optimisations that's a further benefit.
Hugo
I agree with Robert and Hugo, that this /is/ a good idea
/I/ might know the impact, but I still use it all the time to make my code
clearer for the less experienced co-maintainers
> Especially the idea of adding a new ck_ routine just for this
> seems unworthwhile.
>
> (Though I'd always assumed that ck_null wasn't actually called and
> now I see it is. Perhaps there's a good place for an optimization.)
--
H.Merijn Brand Amsterdam Perl Mongers (http://amsterdam.pm.org/)
using perl-5.6.1, 5.8.0, & 5.9.x, and 806 on HP-UX 10.20 & 11.00, 11i,
AIX 4.3, SuSE 8.2, and Win2k. http://www.cmve.net/~merijn/
http://archives.develooper.com/daily...@perl.org/ per...@perl.org
send smoke reports to: smokers...@perl.org, QA: http://qa.perl.org
And I'd like to join the chorus saying it is a Good Thing(TM).
>
> /I/ might know the impact, but I still use it all the time to make my code
> clearer for the less experienced co-maintainers
I prefer to initialize all variables, as a matter of course, even though it is
not required in most circumstances. I think it is an important lesson to teach
new programmers, because it immediately causes them to think about their
assumptions. It's great that Perl will create a new variable on the fly without
being declared first; it's confusing to new programmers.
John
--
John Peacock
Director of Information Research and Technology
Rowman & Littlefield Publishing Group
4720 Boston Way
Lanham, MD 20706
301-459-3366 x.5010
fax 301-429-5747
The chorus has overwhelmed me. I retract.
> >/I/ might know the impact, but I still use it all the time to make my code
> >clearer for the less experienced co-maintainers
>
> I prefer to initialize all variables, as a matter of course, even though it
> is not required in most circumstances. I think it is an important lesson
> to teach new programmers, because it immediately causes them to think about
> their assumptions. It's great that Perl will create a new variable on the
> fly without being declared first; it's confusing to new programmers.
This isn't about a case where there's no declaration, its about making
my $foo = undef;
my @bar = ();
be as efficient as
my $foo;
my @bar;
And the real world solution would have been to define another C macro,
DECLARE_STATIC_INIT_TO_ZERO(type,var), and use that everywhere :-)
Mmmm. This reminds me of a debate that IIRC propagated onto the ARM Linux
list from the main kernel list. The crux of the matter was that some people
were advocating explicitly initialising all static variables to 0
(which is what C would make them by default), whereas others were advocating
removing all the zero initialisations.
The for camp were arguing that it was good to be explicit because it was
documenting that the initial value was important.
The against camp were arguing that it was good to remove them because gcc
(at that time, may still be) would add explicit code to set them to zero, and
wasn't smart enough to optimise them out.
The real solution would have been to fix gcc.
Nicholas Clark
Which I know, and which is what I was talking about too.
FWIW initializing new variables is a good thing for documentation purposes and
for code maintainance. Even with undef or (). Maintainers immediately SEE what
the coder expects
> > The real solution would have been to fix gcc.
>
> And the real world solution would have been to define another C macro,
> DECLARE_STATIC_INIT_TO_ZERO(type,var), and use that everywhere :-)
Since when were the perl5 headers "real world"? :-)
Nicholas Clark
I know, that's why I want the optimization, too! I want an explicit declaration
_and_ efficiency (and a carmel if you don't mind ;~).
Now applied as #22520, along with the array/hash similar optimization.
In fact I *didn't* need to introduce ck_aassign, because in this case
I avoid completely constructing an OP_AASSIGN. (So that's probably
a compilation speedup too :)