On Tue, Apr 01, 2008 at 09:45:30AM -0500, Graham Barr wrote: > On Apr 1, 2008, at 8:49 AM, Nicholas Clark wrote: > >>There's also a related optimization which takes the composition of > >>maps > >>as the map of composition. I.e. these two lines are equivalent, > >>but the > >>latter is more efficient: > >> > >> @xs = map {f($_)} map {g($_)} @ys; > >(which at least avoids needing a full length temporary list, and > >would combine > >with your previous re-write to become > > > > my @xs; > > foreach my $y (@ys) { > > push @xs, f($_) foreach g($y); > > } > > That is probably the best you can do to save memory But following some more thinking and a conversation with Dave Mitchell, even this can't be done in the general case of @xs = map {f($_)} map {g($_)} @ys; It fails 1: if f() or g() are accessing @xs, because they expect @xs to have its original contents 2: if f() or g() throw an exception part way through, because then @xs ends up partly changed, rather than still holding the old contents. I think that the only general case where it is applicable is where it's for the declaration and assignment of a new lexical in one statement, or inside an anonymous array constructor, because in either, there's no possibility of referencing the array being modified, or holding onto a reference to it that could escape outside an eval block. Nicholas ClarkThread Previous | Thread Next