If you just want to use the quicksort algorithm on a standard perl array, then prior to (I think) 5.8.0, perl's built-in sort used that algorithm. From 5.8.0 on, you have to request the quicksort algorithm be used in preference to the now default mergesort using the sort pragma
use sort qw[ _quicksort ];
In the case of the post to which you refer, the OP was looking to save space by storing integers in a packed (or veced) scalar. As the built-in sort doesn't know how to deal with these, it becomes necessary to implement the qsort algorithm yourself. This is the code I knocked up back then to test the performance of a pure perl implementation using vec.
#! perl -slw
use strict;
use Benchmark qw[ timethis ];
local $, = ' ';
our $SIZE ||= 4; our $N ||= 100; $N--;
sub qSortVec {
my( $rVec, $size, $left, $right ) = @_;
if( $left < $right ) {
my( $u, $d ) = ( $left, $right );
my $pivot = vec( $$rVec, ( $u + $d ) / 2, $size );
do {
$u++ while ( vec( $$rVec, $u, $size ) < $pivot );
$d-- while ( vec( $$rVec, $d, $size ) > $pivot );
if( $u <= $d ) {
my $temp = vec( $$rVec, $u, $size );
vec( $$rVec, $u, $size ) = vec( $$rVec, $d, $size );
vec( $$rVec, $d, $size ) = $temp;
$u++; $d--;
}
} while $u <= $d;
qSortVec ( $rVec, $size, $left, $d );
qSortVec ( $rVec, $size, $u, $right );
}
}
srand( 1 );
our $vec ='';
vec( $vec, $_, $SIZE ) = int rand( 1 << $SIZE ) for 0 .. $N;
print map{ vec( $vec, $_, $SIZE ) } 0 .. $N;
our $copy;
timethis( 10, q[ $copy = $vec; qSortVec( \$copy , $SIZE, 0, $N ) ] );
print split"(.{$SIZE})", unpack 'B*', $vec;
print map{ vec( $copy, $_, $SIZE ) } 0 .. $N;
my $res = 0;
$res |= vec( $copy, $_, $SIZE ) > vec( $copy, $_+1, $SIZE ) for 0 ..
+$N-1;
print 'Sort error' if $res;
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
|