in reply to Re^4: In-place sort with order assignment
in thread In-place sort with order assignment

That optimization was introduced here in 2004. Probably, the first stable release to incorporate it was perl 5.10.

update: the optimization is documented in perl5100delta.

  • Comment on Re^5: In-place sort with order assignment

Replies are listed 'Best First'.
Re^6: In-place sort with order assignment
by BrowserUk (Patriarch) on Sep 20, 2010 at 07:47 UTC

    Hm. Do you see anything wrong with this usage that would prevent the in-place optimisation from kicking in?

    perl -E"my @a; $a[$_]=rand for 1..1e6; <>; @a = sort @a; <>"

    Because after the array is populated, memory usage stands at 42mb. After the sort, it jumped to 150MB.

    Which admittedly is substantially better than:

    perl -E"my @a; $a[$_]=rand for 1..1e6; <>; my @b = sort @a; <>"

    Where it leaps from 42MB to 280MB. But it doesn't meet my idea of 'in-place'.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Do you see anything wrong with this usage that would prevent the in-place optimisation from kicking in?

      Yes, you are allocating the values in @a as numbers, but as you compare then as strings they are converted to strings inside the sort and perl caches the string representation.

      A little program to show the effect:

      use Devel::Peek; my @a = (1.1, 2.2); print STDERR "allocated as:\n"; Dump \@a; @a = sort { $a <=> $b } @a; print STDERR "\nsorted as numbers:\n"; Dump \@a; @a = sort @a; print STDERR "\nsorted as strings:\n"; Dump \@a;
      Under my particular OS/perl combination, stringifying a floating point number, increases its memory usage from 32 to 96 bytes.

      A simple (an slow) workaround is to use two auxiliary variables for the comparison:

      @a = sort { my ($b, $c) = ($a, $b); $b cmp $c } @a

        I should've remembered about that :(