Re: hash of arrays sorting

2012-08-21 Thread Shawn H Corey
On Tue, 21 Aug 2012 15:05:33 -0500
Chris Stinemetz  wrote:

> I am trying to sort a hash of arrays ( example below: )
> 
> I would the sort to sort in ascending order the first index of the
> array then the second index of the array.

What have you tried so far? Can we see the code?


-- 
Just my 0.0002 million dollars worth,
  Shawn

Programming is as much about organization and communication
as it is about coding.

_Perl links_
official site   : http://www.perl.org/
beginners' help : http://learn.perl.org/faq/beginners.html
advance help: http://perlmonks.org/
documentation   : http://perldoc.perl.org/
news: http://perlsphere.net/
repository  : http://www.cpan.org/
blog: http://blogs.perl.org/
regional groups : http://www.pm.org/

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: hash of arrays sorting

2012-08-21 Thread Chris Stinemetz
On Tue, Aug 21, 2012 at 3:11 PM, Shawn H Corey wrote:

> On Tue, 21 Aug 2012 15:05:33 -0500
> Chris Stinemetz  wrote:
>
> > I am trying to sort a hash of arrays ( example below: )
> >
> > I would the sort to sort in ascending order the first index of the
> > array then the second index of the array.
>
> What have you tried so far? Can we see the code?
>
> Yes you may.
This is what I have tried so far:

foreach my $cellNo ( keys %hash ) {
print join( "\0", sort {$a<=>$b} @{ $hash{$cellNo} } ),"\n";
}

Thank you in advance,

chris


Re: hash of arrays sorting

2012-08-21 Thread Jim Gibson

On Aug 21, 2012, at 1:05 PM, Chris Stinemetz wrote:

> Hello List,
> 
> I am trying to sort a hash of arrays ( example below: )
> 
> I would the sort to sort in ascending order the first index of the array
> then the second index of the array.

I believe you mean "first element" rather than "first index". The first index 
of your array is 0, and sorting by the indices is a no-operation.

What you want to do is sort the list of keys returned by the keys() function. 
You do this by supplying a subroutine reference to the sort function that 
returns a negative value, zero, or a positive value if the first key yields a 
value less than, equal to, or greater than the value produced by the second 
key. The user-supplied sort function is provided the two keys as the variables 
$a and $b.

If you want to sort by the first element of the arrays referenced by the hash 
values, then you want the values $a->[0] and $b->[0]. Since in your case, these 
values are numbers rather than strings, you want to use the tri-level <=> 
operator (rather than the cmp operator used for strings.)

Thus the expression

sort { $a->[0] <=> $b-{0] } keys %hash;

should return the keys in your desired order.

If you want to include a secondary key, you evaluate an expression that 
compares another array element if the first array elements are equal. This 
expression will do that;

$a->[0] <=> $b->[0] ||
$a->[1] <=> $b->[1]

I will leave it to you to write an actual program incorporating these ideas.

If you want to test your two-key sort, you will need to include some test data 
in which two or more records have the same first element.

> 
> So in this example the arrays would sort to:
> 
> 97,2,120,65
> 219,1,30,33
> 280,3,230,90
> 462,2,270,65
> 
> $VAR1 = {
>  '462-2' => [
>   '462',
>   '2',
>   '270',
>   '65'
> ],
>  '219-1' => [
>   '219',
>   '1',
>   '30',
>   '33'
> ],
>  '280-3' => [
>   '280',
>   '3',
>   '230',
>   '90'
> ],
>  '97-2' => [
>  '97',
>  '2',
>  '120',
>  '65'
> 
>};
> 


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: hash of arrays sorting

2012-08-21 Thread Jim Gibson

On Aug 21, 2012, at 1:23 PM, Jim Gibson wrote:

> 
> On Aug 21, 2012, at 1:05 PM, Chris Stinemetz wrote:
> 
>> Hello List,
>> 
>> I am trying to sort a hash of arrays ( example below: )
>> 
>> I would the sort to sort in ascending order the first index of the array
>> then the second index of the array.
> 
> I believe you mean "first element" rather than "first index". The first index 
> of your array is 0, and sorting by the indices is a no-operation.
> 
> What you want to do is sort the list of keys returned by the keys() function. 
> You do this by supplying a subroutine reference to the sort function that 
> returns a negative value, zero, or a positive value if the first key yields a 
> value less than, equal to, or greater than the value produced by the second 
> key. The user-supplied sort function is provided the two keys as the 
> variables $a and $b.
> 
> If you want to sort by the first element of the arrays referenced by the hash 
> values, then you want the values $a->[0] and $b->[0].

Oops. That is incorrect. I forgot to include access to the hash:

$hash{$a}->[0] <=> $hash{$b}->[0]

Please modify the other references to hash data.


> Since in your case, these values are numbers rather than strings, you want to 
> use the tri-level <=> operator (rather than the cmp operator used for 
> strings.)
> 
> Thus the expression
>   
>   sort { $a->[0] <=> $b-{0] } keys %hash;
> 
> should return the keys in your desired order.
> 
> If you want to include a secondary key, you evaluate an expression that 
> compares another array element if the first array elements are equal. This 
> expression will do that;
> 
>   $a->[0] <=> $b->[0] ||
>   $a->[1] <=> $b->[1]
> 
> I will leave it to you to write an actual program incorporating these ideas.
> 
> If you want to test your two-key sort, you will need to include some test 
> data in which two or more records have the same first element.
> 
>> 
>> So in this example the arrays would sort to:
>> 
>> 97,2,120,65
>> 219,1,30,33
>> 280,3,230,90
>> 462,2,270,65
>> 
>> $VAR1 = {
>> '462-2' => [
>>  '462',
>>  '2',
>>  '270',
>>  '65'
>>],
>> '219-1' => [
>>  '219',
>>  '1',
>>  '30',
>>  '33'
>>],
>> '280-3' => [
>>  '280',
>>  '3',
>>  '230',
>>  '90'
>>],
>> '97-2' => [
>> '97',
>> '2',
>> '120',
>> '65'
>> 
>>   };
>> 
> 


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: hash of arrays sorting

2012-08-21 Thread Chris Stinemetz
 I will leave it to you to write an actual program incorporating these
> ideas.
>
> Thank you Jim for the excelent explanation.

This seems to do the trick.

foreach my $cellNo ( sort { $hash{$a}->[0] <=> $hash{$b}->[0] ||
$hash{$a}->[1] <=> $hash{$b}->[1]  } keys %hash ) {
print join( "\0", @{ $hash{$cellNo} } ),"\n";
}

-Chris


Re: hash of arrays sorting

2012-08-21 Thread Eduardo
On 21/08/12 22:05, Chris Stinemetz wrote:
>  Hello List,
>
> I am trying to sort a hash of arrays ( example below: )
>
> I would the sort to sort in ascending order the first index of the array
> then the second index of the array.
>
> So in this example the arrays would sort to:
>
> 97,2,120,65
> 219,1,30,33
> 280,3,230,90
> 462,2,270,65
>
> $VAR1 = {
>   '462-2' => [
>'462',
>'2',
>'270',
>'65'
>  ],
>   '219-1' => [
>'219',
>'1',
>'30',
>'33'
>  ],
>   '280-3' => [
>'280',
>'3',
>'230',
>'90'
>  ],
>   '97-2' => [
>   '97',
>   '2',
>   '120',
>   '65'
>
> };
>
> Thanks in advance,
>
> Chris
>
Hi, test this:


sub sorted
{
   my ( $naa, $nab ) = $a =~ m|^(\d+)-(\d+)| && ( $1, $2 );
   my ( $nba, $nbb ) = $b =~ m|^(\d+)-(\d+)| && ( $1, $2 );
   return $naa <=> $nba unless $naa == $nba;
   return $nab <=> $nbb;
}


with this loop:

foreach ( sort sorted keys $hash )
{
   print "$_\n";
}


Eduardo.

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: hash of arrays sorting

2012-08-21 Thread Uri Guttman

On 08/21/2012 05:33 PM, Eduardo wrote:

On 21/08/12 22:05, Chris Stinemetz wrote:

  Hello List,

I am trying to sort a hash of arrays ( example below: )

I would the sort to sort in ascending order the first index of the array
then the second index of the array.

So in this example the arrays would sort to:

97,2,120,65
219,1,30,33
280,3,230,90
462,2,270,65

$VAR1 = {
   '462-2' => [
'462',
'2',
'270',
'65'
  ],
   '219-1' => [
'219',
'1',
'30',
'33'
  ],
   '280-3' => [
'280',
'3',
'230',
'90'
  ],
   '97-2' => [
   '97',
   '2',
   '120',
   '65'

 };

Thanks in advance,

Chris


Hi, test this:


sub sorted
{
my ( $naa, $nab ) = $a =~ m|^(\d+)-(\d+)| && ( $1, $2 );
my ( $nba, $nbb ) = $b =~ m|^(\d+)-(\d+)| && ( $1, $2 );
return $naa <=> $nba unless $naa == $nba;
return $nab <=> $nbb;


since <=> will return 0 (false) if they are == you can just do this:
return $naa <=> $nba || $nab <=> $nbb;

but that is a lot of coding to run for each sort comparison. check out 
Sort::Maker for ways to do that with much less effort and faster as well.


uri



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: hash of arrays sorting

2012-08-21 Thread Eduardo
On 22/08/12 00:35, Uri Guttman wrote:
> On 08/21/2012 05:33 PM, Eduardo wrote:
>> On 21/08/12 22:05, Chris Stinemetz wrote:
>>>   Hello List,
>>>
>>> I am trying to sort a hash of arrays ( example below: )
>>>
>>> I would the sort to sort in ascending order the first index of the
>>> array
>>> then the second index of the array.
>>>
>>> So in this example the arrays would sort to:
>>>
>>> 97,2,120,65
>>> 219,1,30,33
>>> 280,3,230,90
>>> 462,2,270,65
>>>
>>> $VAR1 = {
>>>'462-2' => [
>>> '462',
>>> '2',
>>> '270',
>>> '65'
>>>   ],
>>>'219-1' => [
>>> '219',
>>> '1',
>>> '30',
>>> '33'
>>>   ],
>>>'280-3' => [
>>> '280',
>>> '3',
>>> '230',
>>> '90'
>>>   ],
>>>'97-2' => [
>>>'97',
>>>'2',
>>>'120',
>>>'65'
>>>
>>>  };
>>>
>>> Thanks in advance,
>>>
>>> Chris
>>>
>> Hi, test this:
>>
>>
>> sub sorted
>> {
>> my ( $naa, $nab ) = $a =~ m|^(\d+)-(\d+)| && ( $1, $2 );
>> my ( $nba, $nbb ) = $b =~ m|^(\d+)-(\d+)| && ( $1, $2 );
>> return $naa <=> $nba unless $naa == $nba;
>> return $nab <=> $nbb;
>
> since <=> will return 0 (false) if they are == you can just do this:
> return $naa <=> $nba || $nab <=> $nbb;
>
yes, ofcourse, it's the same

> but that is a lot of coding to run for each sort comparison. check out
> Sort::Maker for ways to do that with much less effort and faster as well.
>
> uri

yes, ofcourse, (I repeat me), a lot of working, with a few register
works well, but it's not the best.

by hand, this is faster, maybe not the fastest,

my %cache = ();
foreach ( keys %$hash )
{
   my ( $naa, $nab ) = $_ =~ m|^(\d+)-(\d+)|;
   $cache{ ($naa * 100 + $nab ) } = $_;
}

foreach ( sort { $a <=> $b } keys %cache )
{
   print "[*] $cache{$_}\n";
}

without repeating code, use a formula forcaching keys.
you only need to know the size of the sendond keys.


how would you do with Sort::Maker?

thanks a lot, Uri Guttman

Eduardo.

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: hash of arrays sorting

2012-08-21 Thread Uri Guttman

On 08/21/2012 08:29 PM, Eduardo wrote:

On 22/08/12 00:35, Uri Guttman wrote:




my %cache = ();
foreach ( keys %$hash )
{
my ( $naa, $nab ) = $_ =~ m|^(\d+)-(\d+)|;
$cache{ ($naa * 100 + $nab ) } = $_;
}


that is a variant of the orcish manoever which is supported by sort::maker.


foreach ( sort { $a <=> $b } keys %cache )
{
print "[*] $cache{$_}\n";
}

without repeating code, use a formula forcaching keys.
you only need to know the size of the sendond keys.


how would you do with Sort::Maker?

i don't have time to show an example now but it is much cleaner looking. 
all you need to do is code up how you extract each key from the data set 
and how it gets sorted (number vs string, etc.). it makes sorting into a 
declarative problem instead of a coding problem.


uri


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: hash of arrays sorting

2012-08-22 Thread Eduardo
On 22/08/12 03:49, Uri Guttman wrote:
> On 08/21/2012 08:29 PM, Eduardo wrote:
>> how would you do with Sort::Maker?
> i don't have time to show an example now but it is much cleaner
> looking. all you need to do is code up how you extract each key from
> the data set and how it gets sorted (number vs string, etc.). it makes
> sorting into a declarative problem instead of a coding problem.
>
> uri

do'nt worry, that's what I'm

Thanks a lot for forcing me to study sorting in perl.

This morning I read sort_paper[*] apparently written by someone expert
with the subject, and also Chapter 2 item 22 Effective perl, to get an
overview.

After that I have a vague idea and got this code:

my @sorted = map  { $_->[0] }
 sort { $a->[1] <=> $b->[1] }
 map  { [ $_, /^(\d+)-(\d+)/ && ($1 * 100 + $2) ] }
 keys %$hash;

Tonight I reread the Sort::Maker manual, now I understand and I was able
to create this code:

my $sorted = make_sorter( name => 'sort_func',
  orcish => 1,
  number => '/^(\d+)-(\d+)/ && ($1 * 100 + $2)'
that generate this:

sub {
   
my ( %or_cache1 ) ;

   
sort {
(
  ( $or_cache1{$a} ||=
do{ my ($val) = map { /^(\d+)-(\d+)/ && ($1 * 100 + $2) } $a ;
$val } )
<=>
  ( $or_cache1{$b} ||=
do{ my ($val) = map { /^(\d+)-(\d+)/ && ($1 * 100 + $2) } $b ;
$val } )
)

} @_  ;
}


I did not think that I obtained so high performance in a short time, I
just subscribe to the list.

It's a pity Sort::Maker not in Debian

Thanks a lot

* http://www.sysarch.com/Perl/sort_paper.html


Eduardo.

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: hash of arrays sorting

2012-08-22 Thread Salvador Fandino
On 08/22/2012 10:34 PM, Eduardo wrote:
> On 22/08/12 03:49, Uri Guttman wrote:
>> On 08/21/2012 08:29 PM, Eduardo wrote:
>>> how would you do with Sort::Maker?
>> i don't have time to show an example now but it is much cleaner
>> looking. all you need to do is code up how you extract each key from
>> the data set and how it gets sorted (number vs string, etc.). it makes
>> sorting into a declarative problem instead of a coding problem.
>>
>> uri
> 
> do'nt worry, that's what I'm
> 
> Thanks a lot for forcing me to study sorting in perl.
> 
> This morning I read sort_paper[*] apparently written by someone expert
> with the subject, and also Chapter 2 item 22 Effective perl, to get an
> overview.
> 
> After that I have a vague idea and got this code:
> 
> my @sorted = map  { $_->[0] }
>  sort { $a->[1] <=> $b->[1] }
>  map  { [ $_, /^(\d+)-(\d+)/ && ($1 * 100 + $2) ] }
>  keys %$hash;
> 
> Tonight I reread the Sort::Maker manual, now I understand and I was able
> to create this code:
> 
> my $sorted = make_sorter( name => 'sort_func',
>   orcish => 1,
>   number => '/^(\d+)-(\d+)/ && ($1 * 100 + $2)'
> that generate this:
> 
> sub {
>
> my ( %or_cache1 ) ;
> 
>
> sort {
> (
>   ( $or_cache1{$a} ||=
> do{ my ($val) = map { /^(\d+)-(\d+)/ && ($1 * 100 + $2) } $a ;
> $val } )
> <=>
>   ( $or_cache1{$b} ||=
> do{ my ($val) = map { /^(\d+)-(\d+)/ && ($1 * 100 + $2) } $b ;
> $val } )
> )
> 
> } @_  ;
> }
> 
> 
> I did not think that I obtained so high performance in a short time, I
> just subscribe to the list.
> 
> It's a pity Sort::Maker not in Debian

There is also Sort::Key, available in Debian testing and unstable, and
which is usually faster than Sort::Maker and also Sort::Key::Radix, even
faster when sorting by numeric keys but not available in Debian.

  use Sort::Key qw(ukeysort);

  my @sorted = ukeysort { /^(\d+)-(\d+)/
or die "bad key $_";
  $1 * 100 + $2 } @data;


The 'u' prefix in 'ukeysort' specifies that the sorting key is an
unsigned integer.



-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: hash of arrays sorting

2012-08-23 Thread Uri Guttman

On 08/23/2012 02:54 AM, Salvador Fandino wrote:



It's a pity Sort::Maker not in Debian


There is also Sort::Key, available in Debian testing and unstable, and
which is usually faster than Sort::Maker and also Sort::Key::Radix, even
faster when sorting by numeric keys but not available in Debian.

   use Sort::Key qw(ukeysort);

   my @sorted = ukeysort { /^(\d+)-(\d+)/
 or die "bad key $_";
   $1 * 100 + $2 } @data;


The 'u' prefix in 'ukeysort' specifies that the sorting key is an
unsigned integer.


you are comparing apples and oranges. your module provides numerous 
specialized sort subs (like php does) which means the coder has to 
remember or lookup what each one does. i counted at least 32 similarly 
names subs which is very confusing. having a single sub with a flexible 
api is a much better interface.


your claim for it being faster needs backing with benchmarks with 
multiple keys. single key sorts are fast with just the sort function as 
is. since your multikey sorts must use a map/sort/map method, again 
showing how they are faster then the GRT would be interesting.


uri



--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: hash of arrays sorting

2012-08-23 Thread Rob Coops
On Thu, Aug 23, 2012 at 9:10 AM, Uri Guttman  wrote:

> On 08/23/2012 02:54 AM, Salvador Fandino wrote:
>
>
>>> It's a pity Sort::Maker not in Debian
>>>
>>
>> There is also Sort::Key, available in Debian testing and unstable, and
>> which is usually faster than Sort::Maker and also Sort::Key::Radix, even
>> faster when sorting by numeric keys but not available in Debian.
>>
>>use Sort::Key qw(ukeysort);
>>
>>my @sorted = ukeysort { /^(\d+)-(\d+)/
>>  or die "bad key $_";
>>$1 * 100 + $2 } @data;
>>
>>
>> The 'u' prefix in 'ukeysort' specifies that the sorting key is an
>> unsigned integer.
>>
>
> you are comparing apples and oranges. your module provides numerous
> specialized sort subs (like php does) which means the coder has to remember
> or lookup what each one does. i counted at least 32 similarly names subs
> which is very confusing. having a single sub with a flexible api is a much
> better interface.
>
> your claim for it being faster needs backing with benchmarks with multiple
> keys. single key sorts are fast with just the sort function as is. since
> your multikey sorts must use a map/sort/map method, again showing how they
> are faster then the GRT would be interesting.
>
> uri
>
>
>
>
> --
> To unsubscribe, e-mail: beginners-unsubscr...@perl.org
> For additional commands, e-mail: beginners-h...@perl.org
> http://learn.perl.org/
>
>
>
As said before is all needs benchmarking to see what is really faster and
how much faster actually (a 1% increase in time but a much easier interface
or far less dependencies could be preferable in some cases). If I had to
deal with this I would probably use the map, sort, map solution proposed
before as this solution is available on all platforms and therefore highly
portable (in the environment I work in there is a range of perl versions
from 5.005 to the latest release on a wide range of operating systems)

As for faster or slower, have a look at the size of the hash you are
sorting, if the hash only has a few hundred keys the speed difference might
not even be noticeable (a few ms more or less in a long running process is
not going to be noticed). On the other hand is there is tens of thousands
of keys and the sorting time is reduced an awful lot with this sort being
the main time consumer within the overall process... It might be worth
installing the module even if it is a slightly painful thing in some
environments.

Regards,

Rob


Re: hash of arrays sorting

2012-08-23 Thread Salvador Fandino
On 08/23/2012 09:10 AM, Uri Guttman wrote:
> On 08/23/2012 02:54 AM, Salvador Fandino wrote:
> 
>>>
>>> It's a pity Sort::Maker not in Debian
>>
>> There is also Sort::Key, available in Debian testing and unstable, and
>> which is usually faster than Sort::Maker and also Sort::Key::Radix, even
>> faster when sorting by numeric keys but not available in Debian.
>>
>>use Sort::Key qw(ukeysort);
>>
>>my @sorted = ukeysort { /^(\d+)-(\d+)/
>>  or die "bad key $_";
>>$1 * 100 + $2 } @data;
>>
>>
>> The 'u' prefix in 'ukeysort' specifies that the sorting key is an
>> unsigned integer.
> 
> you are comparing apples and oranges.

I don't thing so. I am comparing two modules that generate sorters. The
may have different APIs, but at the functional level they are the same
thing.

> your module provides numerous
> specialized sort subs (like php does) which means the coder has to
> remember or lookup what each one does. i counted at least 32 similarly
> names subs which is very confusing.

Actually Sort::Key provides both, you can choose between the
Sort::Key::Maker declarative API that allows to create multi-key sorting
subs and the prebuild mono-key sorters from Sort::Key (and also, the
jit-build multi-key sorters of Sort::Key::Multi).

> having a single sub with a flexible api is a much better interface.

Well, it depends, the flexible API of Sort::Maker results in code that's
probably more legible and easy to understand without reading the module
documentation first.

On the other hand, using the pre-build sorters from Sort::Key results in
more concise and simpler code. If you need to include sorting operations
in your code frequently you get to appreciate that.

> your claim for it being faster needs backing with benchmarks with
> multiple keys. single key sorts are fast with just the sort function as
> is. since your multikey sorts must use a map/sort/map method, again
> showing how they are faster then the GRT would be interesting.

IIRC, a long time ago I send you a patch for Sort::Maker benchmarking
script incorporating Sort::Key variants that showed how faster my module
can be. I would try to find it and send it to you again.



-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: hash of arrays sorting

2012-08-23 Thread Salvador Fandino

> IIRC, a long time ago I send you a patch for Sort::Maker benchmarking
> script incorporating Sort::Key variants that showed how faster my module
> can be. I would try to find it and send it to you again.

Well, I have been unable to find it... but I have redone it :-)

Attached are the patch that adds tests for Sort::Key variants to your
testing/benchmarking scripts in Sort::Maker and the output I get when I
run them on my computer.

You can see that Sort::Key sorters are usually between 2 and 3 times
faster than any variant generated by Sort::Maker.

To be fair, I have to said that in my experience, as the size of the
lists to be sorted increases, the gap becomes smaller and for really
large data sets, Sort::Key sorters are around 1.5 times faster than the
GRT ones generated by Sort::Maker.

Memory usage is usually also quite lower in Sort::Key. That's an
important thing to consider when your data sets are really big.

diff --git a/t/common.pm b/t/common.pm
index 1ac5082..8bdd708 100644
--- a/t/common.pm
+++ b/t/common.pm
@@ -44,6 +44,7 @@ sub test_driver {
 		}
 
 		make_test_sorters( $test, $default_styles ) ;
+make_sk_sorters($test);
 
 		if ( $test->{error} ) {
 
@@ -131,6 +132,7 @@ sub benchmark_driver {
 		$test->{input_sets} = [generate_data( $test, $default_sizes )] ;
 
 		make_test_sorters( $test, $default_styles ) ;
+make_sk_sorters($test) ;
 
 		run_benchmarks( $test, $duration ) ;
 	}
@@ -146,7 +148,7 @@ sub run_benchmarks {
 
 		$entries{ $name } = $name =~ /ref_in/ ?
 			sub { my @sorted = $sorter->( $in_ref ) } :
-			sub { my @sorted = $sorter->( @input ) } ;
+sub { my @sorted = $sorter->( @input ) } ;
 	}
 
 	$entries{ 'gold' } =
@@ -170,7 +172,19 @@ sub generate_data {
 	my( $test, $default_sizes ) = @_ ;
 
 	my $gen_code = $test->{gen} ;
-	$gen_code or die "no 'gen' code for test $test->{name}" ;
+	if( not defined $gen_code) {
+if ($test->{data}) {
+my $data = $test->{data};
+my $ix = -1;
+$gen_code = sub {
+$ix = ($ix + 1) % @$data;
+$data->[$ix]
+}
+}
+else {
+die "no 'gen' code for test $test->{name}" ;
+}
+}
 
 	my @sizes = @{ $test->{sizes} || $default_sizes || [100] } ;
 
@@ -241,6 +255,71 @@ sub make_test_sorters {
 	return 1 ;
 }
 
+my %pre_mod = map { $_ => 1 } qw(signed signed_float unsigned unsigned_float);
+my %post_mod = map { $_ => 1 } qw(descending ascending fixed varying no_case case);
+
+sub make_sk_sorters {
+my $test = shift;
+if (eval { require Sort::Key; 1 }) {
+unless ($test->{ref_in} or $test->{ref_out}) {
+my $args = $test->{args} or die "$test->{name} has no args\n" ;
+my $arg_sets = ( ref $args eq 'HASH' ) ? $args : { '' => $args } ;
+TEST: foreach my $arg_name ( sort keys %{$arg_sets} ) {
+		my $test_args = $arg_sets->{$arg_name} ;
+my $sort_name = $arg_name ? "SK_$arg_name" : "SK";
+my $init = '';
+my @code;
+my @types;
+my @test_args = @$test_args;
+while (@test_args) {
+my ($type, %mod);
+while (1) {
+$type = shift @test_args;
+last unless $pre_mod{$type};
+$mod{$type} = 1;
+die "bad type specification" unless @test_args;
+}
+while (@test_args and $post_mod{$test_args[0]}) {
+my $mod = shift @test_args;
+$mod{$mod} = 1;
+if ($mod =~ /^(?:fixed|no_case)$/) {
+next TEST;
+}
+}
+
+my $code = (@test_args ? shift(@test_args) : '$_');
+if ($type eq 'init_code') {
+$init = $code;
+}
+else {
+if (!ref($code) and $type =~ /^(?:string|number)$/) {
+if ($type eq 'number') {
+if ($mod{unsigned}) {
+$type = 'uint';
+}
+if ($mod{signed}) {
+$type = 'int';
+}
+}
+$type = "-$type" if $mod{descending};
+push @types, $type;
+push @code, $code;
+}
+else {
+warn "unsupported argument, type: $type, ref(code): " . ref($code);
+next TEST;
+}
+}
+}
+my $sub