david wrote:
> Steven Massey wrote:
>
> >
> > I have an array, each line contains fields seperated by ":"
> > I want to sort the array numerically ascending by the last field.
> >
> > my thoughts are to split fields into seperate arrays, go through
> > the last array in a comparing process, moving each row index in the
> > original array to reflect the sort. ( I found this hard to explain)
> >
> > Do any of you some tips as to how to approach this ??
> >
>
> not suprisingly, there are many approach to this. i actually take
> some time to benchmark some of the most populars and see what will be
> better:
>
> #!/usr/bin/perl -w
> use strict;
>
> use Benchmark;
>
> my @array = ('abcd:xxx:1234','yyy:xxx:2','a:b:12');
>
> sub sr_s{
> for(sort {(my $a_value = $a) =~ s/.+:.+://;
> (my $b_value = $b) =~ s/.+:.+://;
> $a_value <=> $b_value} @array){;} }
>
> sub split_s{
> for(sort {my @a_val = split(/:/,$a);
> my @b_val = split(/:/,$b);
> $a_val[2] <=> $b_val[2]} @array){;} }
>
> sub split_ref_s{
> for(sort {(split(/:/,$a))[2] <=> (split(/:/,$b))[2]}
> @array){;} }
>
> sub reg_s{
> for(sort { my ($i) = $a =~ /(\d+)$/;
> my ($j) = $b =~ /(\d+)$/; $i <=> $j} @array){;} }
>
> sub reg_ref_s{
> for(sort {($a =~ /(\d+)$/)[0] <=> ($b =~
> /(\d+)$/)[0]} @array){;}
> }
>
> timethese(99999,{split_s => \&split_s,
> split_ref_s => \&split_ref_s,
> reg_s => \®_s,
> reg_ref_s => \®_ref_s,
> sr_s => \&sr_s});
>
> __END__
>
> prints:
>
> Benchmark: timing 99999 iterations of
>
> reg_ref_s, reg_s, split_ref_s, split_s, sr_s...
>
> reg_ref_s: 35 wallclock secs (15.13 usr + 0.02 sys = 15.15 CPU) @
> 6600.59/s (n=99999)
>
> reg_s: 40 wallclock secs (18.17 usr + 0.02 sys = 18.19 CPU) @
> 5497.47/s (n=99999)
>
> split_ref_s: 30 wallclock secs (13.87 usr + 0.01 sys = 13.88 CPU) @
> 7204.54/s (n=99999)
>
> split_s: 54 wallclock secs (23.12 usr + 0.03 sys = 23.15 CPU) @
> 4319.61/s (n=99999)
>
> sr_s: 31 wallclock secs (13.37 usr + 0.01 sys = 13.38 CPU) @
> 7473.77/s (n=99999)
>
> looks like sr_s is the winner.
>
> david
Don't forget the Schwartzian Transform:
map $_->[0],
sort {$a->[1] <=> $b->[1]}
map [$_, (split /:/, $_)[-1]],
@array
This will be quicker than the other methods, especially as the array size
grows. Try your benchmark with an array of say 10, or 100 elements.
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]