[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]

[PATCH] honoring void context for map()



Hi,

Abigail raised this issue on clpmc: using map in void context should not
be regarded as a stylistical bug in the programmer but rather considered
a bug in the Perl interpreter that should be able to optimize the return
list away.

The attached patch against bleadperl does that. The trivialness of it
makes me wonder whether I perhaps was a little too simplistic. However,
all tests pass. This results in a nice speed-up:

    my @a = (0 .. 1_000_000);
    for (0 .. 10) {
        map { $_++ } @a;
    }

A naive tests using time(1) gives:

    real    0m12.748s
    user    0m12.700s
    sys     0m0.050s

versus (with the patch):

    real    0m8.791s
    user    0m8.700s
    sys     0m0.090s

The difference is even more obvious when using 'map $_++, @a'. map() in
void context is now almost as fast as a for-loop.

The runtime in scalar and list context are not affected by this patch (I
tested it).

Unfortunately, I wasn't able to further optimize scalar context. I
suppose it should somehow be possible as well.

Tassilo
-- 
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
--- pp_ctl.c~	2003-09-04 10:56:46.000000000 +0200
+++ pp_ctl.c	2003-09-04 10:58:45.000000000 +0200
@@ -893,6 +893,7 @@
 PP(pp_mapwhile)
 {
     dSP;
+    I32 gimme = GIMME_V;
     I32 items = (SP - PL_stack_base) - *PL_markstack_ptr; /* how many new items */
     I32 count;
     I32 shift;
@@ -903,7 +904,7 @@
     ++PL_markstack_ptr[-1];
 
     /* if there are new items, push them into the destination list */
-    if (items) {
+    if (items && gimme != G_VOID) {
 	/* might need to make room back there first */
 	if (items > PL_markstack_ptr[-1] - PL_markstack_ptr[-2]) {
 	    /* XXX this implementation is very pessimal because the stack
@@ -947,7 +948,6 @@
 
     /* All done yet? */
     if (PL_markstack_ptr[-1] > *PL_markstack_ptr) {
-	I32 gimme = GIMME_V;
 
 	(void)POPMARK;				/* pop top */
 	LEAVE;					/* exit outer scope */

Follow-Ups from:
david nicol <whatever@davidnicol.com>
Kurt Starsinic <kstar@cpan.org>
Rafael Garcia-Suarez <rgarciasuarez@free.fr>

[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]