I have an 2-byte string, an I wish to extract the numeric value of its 4 nybbles into an array. Below I have 5 working variations, but they are all quite complex and quite slow.

print map{hex} (split'', unpack 'h4', $n)[2,3,0,1]; #! Gives >> 15 0 0 15 print map{ ( ord($_) & 0xf0 ) >> 4, ord($_) & 0x0f } split//, $n; #! Gives >> 15 0 0 15 print map{ vec $n, $_, 4 } 0 .. 3; #! Gives >> 0 15 15 0 print +(map{ vec $n, $_, 4 } 0 .. 3)[2,3,0,1]; #! Gives >> 15 0 0 15 print map{ ( unpack( 'n' , $n ) >> ( 4 * $_ ) ) & 0xf } 0 .. 3; #! Gives >> 15 0 0 15 $n = unpack 'n', $n; print map{ ($n >>( 4 * $_ )) & 0xf } 0 .. 3; #! Gives >> 15 0 0 15

There has to be a better way?

Code and benchmark

#! perl -slw use strict; use Benchmark qw[cmpthese]; our $n = "\xf0\x0f"; print unpack 'hhhh', $n; #! Gives >> 0 f print unpack 'h h h h', $n; #! Gives >> 0 f print unpack 'h2 h2', $n; #! Gives >> 0f f0 +# two 2-byte strings print unpack 'h4', $n; #! Gives >> 0ff0 # + a single 4 char string print map{hex} (split'', unpack 'h4', $n)[2,3,0,1]; #! + Gives >> 15 0 0 15 print map{ ( ord($_) & 0xf0 ) >> 4, ord($_) & 0x0f } split//, $n; #! + Gives >> 15 0 0 15 print map{ vec $n, $_, 4 } 0 .. 3; #! + Gives >> 0 15 15 0 print +(map{ vec $n, $_, 4 } 0 .. 3)[2,3,0,1]; #! + Gives >> 15 0 0 15 print map{ ( unpack( 'n' , $n ) >> ( 4 * $_ ) ) & 0xf } 0 .. 3; #! + Gives >> 15 0 0 15 $n = unpack 'n', $n; print map{ ($n >>( 4 * $_ )) & 0xf } 0 .. 3; #! + Gives >> 15 0 0 15 our @nybbles = (); cmpthese( -1, { #! 1 map, 4 hexes (Just my luck!), a split, an unpack, a list and +a slice. map_hex_split_unpack => q[ @nybbles = map{hex} (split'', unpack 'h4', $n)[2,3,0,1]; ], #! 1 map, 2 ords, 2 ands, shift right 4, 1 split and a partridge i +n a pair tree! map_ord_and_shift_split => q[ @nybbles = map{ ( ord($_) & 0xf0 ) >> 4, ord($_) & 0x0f } sp +lit//, $n; ], #! 1 map, 4 vecs, two lists, one splice. Phew! map_vec_lists_splice => q[ @nybbles = map{ ( unpack( 'n' , $n ) >> ( 4 * $_ ) ) & 0xf } + 0 .. 3; ], #! 1map, 4 X ( unpack, shift, mult, & ), a list #! and enough brackets to keep a LISP afficianardo happy for days. map_unpack_shift_mult_and_list => q[ @nybbles = map{ ( unpack( 'n' , $n ) >> ( 4 * $_ ) ) & 0xf } + 0 .. 3; ], #! Factor out the unpack. Slightly better. unpack_map_shift_and_list => q[ $n = unpack 'n', $n; @nybbles = map{ ( $n >> ( 4 * $_ ) ) & +0xf } 0 .. 3; ], }); __DATA__ C:\test>test map_hex_split_unpack: 1 wallclock secs @ 10317.66/s (n=107 +51) map_ord_and_shift_split: 1 wallclock secs @ 7324.69/s (n= 76 +25) map_unpack_shift_mult_and_list: 2 wallclock secs @ 12869.53/s (n=146 +97) map_vec_lists_splice: 1 wallclock secs @ 12954.41/s (n=133 +56) unpack_map_shift_and_list: 1 wallclock secs @ 15328.34/s (n=153 +59) Rate MOASP MHSU MUSMUL MVLS +UMSL map_ord_and_shift_split 7325/s -- -29% -43% -43% +-52% map_hex_split_unpack 10318/s 41% -- -20% 20% +-33% map_unpack_shift_mult_and_list 12870/s 76% 25% -- -1% +-16% map_vec_lists_splice 12954/s 77% 26% 1% -- +-15% unpack_map_shift_and_list 15328/s 109% 49% 19% 18% + -- C:\test>

In anyone has/or can produce a Inline C or XS equivalent built for AS 633 or AS 802, I'd sell my soul er... be very grateful>


Examine what is said, not who speaks.

The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.


In reply to Nybbles take to long by BrowserUk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.