[tpm] OID sorting

John Macdonald john at perlwolf.com
Wed May 6 10:15:39 PDT 2009


On Wed, May 06, 2009 at 12:06:51PM -0400, Fulko Hew wrote:
> I just thought I'd follow up on the discussion I started last week.
> (Thanks to all who participated!)
> 
> Attached is my current version of the test harness based on
> Abram's work, and most if not all supplied routines and
> suggestions (even your's Uri, now that I had the time to
> look!)
> 
> My conclusions:
> 
> 1/ Abram's 'nounpacksort' was the most efficient.
> 2/ Uri's rehash of my original code wins as the most readable.
>    (I know it had ugly 'C' constructs, but I couldn't think of a better
>    more Perl'ish way (see bonus points below))
> 3/ My original code wasn't all that bad :-)
> 4/ Adding the tuple idea yields noticeable improvements.
> 
> Uri also gets bonus points for showing me that I could do this
> kind of in-place substitution... on a list:
> 
>    s/ //g foreach @oids;
> 
> Uri also gets extra bonus points for teaching me to use
> regex's with embedded code.  I always knew it could be done
> but never spent the time to learn it, nor recognize when
> it would be useful.  Now (dammit), thanks to Uri, I know.
> 
>     s/(\d+)/sprintf('%8s', $1)/ge foreach @oids;
> 
> And oh yes... printing the 'number as a string' _is_ faster
> than printing a 'number as a number'!
> 
> Here's the benchmark results:
> 
>                      s/iter    Improvement
> abram_whilecmp         7.05             --
> indy_slow_sort         6.89             2%
> henrys_sort            5.52            28%
> fulko_sort_uri         1.79           294%
> fulko_sort_orig        1.77           299%
> abram_swartzpacksort   1.55           356%
> abram_packsort         1.41           400%
> fulko_sort             1.14           519%
> abram_nounpacksort    0.905           679%
> 
> Oh... another thing I learned...
> 
> When running benchmarks... turn off Centrino auto-CPU-speed-mechanism!
> I was having a hell of a time trying to figure out
> why my results were always all over the map.  :-(
> 
> Finally, for those who want to see the (current) winners,
> without having to look at the attachment, they are:
> 
> For Readability:
> 
> sub fulko_sort_uri {
>     my @oids = @_;
> 
>     s/(\d+)/sprintf('%8s', $1)/ge foreach @oids;
>     @oids = sort @oids;
>     s/ //g foreach @oids;
>     return @oids;
> }
> 
> For Fastest:
> 
> sub abram_nounpacksort {
>     my @data = map { [ split(/\./, $_) ] } @_;
>     my @sorted = map { $_->[1] }
>         sort { $a->[0] cmp $b->[0] }
>             map { [pack("N*",@$_),$_] } @data;
>     @sorted = map { join(".",@$_) } @sorted;
>     return @sorted;
> }

Since the numbers are the only significant content of the oid,
I wonder whether it would be cheaper to recreate it at the end.
Sorting with no sort function is faster than having to do
2 array subscripts for each compare. (Maybe that was what
abram_packsort did?)

sub jmm {
    return
        map { join( '.', unpack('N*', $_) ) }
        sort
        map { pack('N*', split(/\./, $_) ) }
        @_;
}

Instead of a 2-element array, I sometimes just use a single
string, consisting of a leading portion which is directly
sortable, if necessary a marker, and finally the original
string.  The final map just removes the leading string (and
the marker).


> _______________________________________________
> toronto-pm mailing list
> toronto-pm at pm.org
> http://mail.pm.org/mailman/listinfo/toronto-pm



More information about the toronto-pm mailing list