Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Re^2: sort an array with +ve & -ve numbers in it

by eric256 (Parson)
on Apr 03, 2009 at 13:16 UTC ( #755264=note: print w/ replies, xml ) Need Help??

in reply to Re: sort an array with +ve & -ve numbers in it
in thread sort an array with +ve & -ve numbers in it

Ummm...isn't a sort a bit easier and simpler?

my @array = ( 99, 67, 0, -100, -38, 98); my ($min, $max) = (sort @array)[0,-1];

Eric Hodges

Comment on Re^2: sort an array with +ve & -ve numbers in it
Download Code
Replies are listed 'Best First'.
Re^3: sort an array with +ve & -ve numbers in it
by philipbailey (Chaplain) on Apr 03, 2009 at 14:38 UTC
    Easier and simpler, but less efficient (O n log n, perhaps) than jwkrahn's approach (O n). Of course this won't matter for small data sets.
      Easier and simpler, but less efficient

      Woah! I would benchmark that before making such a statement. I expect you'll need a seriously huge list before the O(n log n) starts to lose to your straight O(n).

      There's no debate that it will, but the problem is the 0(n) algorithm is using a comparatively large number of slow ops, where as the sort compiles down into a single op, and there you're running at C speed (simple {$a <=> $b} blocks are recognised and special-cased during the parse). This will drown out the extra cost for a long, long time (that is: for a long list of values). On my machine, the cross-over occurs between 100 000 and 1 000 000 elements (and I had to run the million element benchmark for 15 seconds in order to give it enough time to settle down)

      Rate with_scan_1 with_sort_1 with_scan_1 35662/s -- -53% with_sort_1 76332/s 114% -- Rate with_scan_2 with_sort_2 with_scan_2 6838/s -- -40% with_sort_2 11437/s 67% -- Rate with_scan_3 with_sort_3 with_scan_3 759/s -- -11% with_sort_3 853/s 12% -- Rate with_sort_4 with_scan_4 with_sort_4 62.6/s -- -18% with_scan_4 76.2/s 22% -- Rate with_sort_5 with_scan_5 with_sort_5 3.38/s -- -47% with_scan_5 6.38/s 89% -- s/iter with_sort_6 with_scan_6 with_sort_6 4.88 -- -66% with_scan_6 1.65 196% --

      And since either choice is crazy fast enough for me, I'd throw my lot in with the more succinct version -- less chance of introducing semantic mistakes and off-by-one errors). For instance, I had to think for a little while about how you initialised $min and $max...

      • another intruder with the mooring in the heart of the Perl

Re^3: sort an array with +ve & -ve numbers in it
by lostjimmy (Chaplain) on Apr 03, 2009 at 15:26 UTC

    As already stated by ikegami, you really need to use the numerical sort: sort {$a <=> $b} @array

    Try changing your data set to my @array = ( -10, 99, 67, 0, -100, -38, 98) and using that sort routine. This is probably the problem the OP is having. You're going to get -10 as the minimum.

      Very true, corrected code:

      my @array = ( 99, 67, 0, -100, -38, 98); my ($min, $max) = (sort {$a <=> $b} @array)[0,-1];

      Update: Cut n paste error fixed, thanks plobsing and ikegami

      Eric Hodges

        Typo alert: you have 2 sorts. The result is that you sort alphabetically after having sorted numerically.

        Unfortunately, your test dataset doesn't show the problem. Try adding 100 to the data.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://755264]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (9)
As of 2015-11-30 12:54 GMT
Find Nodes?
    Voting Booth?

    What would be the most significant thing to happen if a rope (or wire) tied the Earth and the Moon together?

    Results (770 votes), past polls