use strict; use warnings; use Time::HiRes qw(time); my ( \$x , \$y , \$iters ) = ( -890394, 100, 5_000_000 ); my ( \$xx, \$yy, \$n ); ## # sub _pack { # my ( \$x, \$y ) = @_; # return # \$x < 0 ? -( abs(\$x) << 16 | \$y ) : \$x << 16 | \$y; # } # # sub _unpack { # my ( \$n ) = @_; # return \$n < 0 # ? ( -( abs(\$n) >> 16 ), abs(\$n) & 0xFFFF ) # : ( \$n >> 16 , \$n & 0xFFFF ); # } ## bench( "bitops ", sub { # map two integers \$x and \$y into \$n # support negative \$x only for ( 1 .. \$iters ) { \$n = \$x < 0 ? -( abs(\$x) << 16 | \$y ) : \$x << 16 | \$y; ( \$xx, \$yy ) = \$n < 0 ? ( -( abs(\$n) >> 16 ), abs(\$n) & 0xFFFF ) : ( \$n >> 16 , \$n & 0xFFFF ); } }); ## # sub _pack { # my ( \$x, \$y ) = @_; # # bits 0,1 indicate neg flag for \$x,\$y respectively # return # ( abs(\$x) << 18 ) + ( \$x < 0 ? 1 : 0 ) + # ( abs(\$y) << 2 ) + ( \$y < 0 ? 2 : 0 ); # } # # sub _unpack { # my ( \$n ) = @_; # # bits 0,1 indicate neg flag for \$x,\$y respectively # return ( # \$n & 0x1 ? -(\$n >> 18 ) : \$n >> 18, # \$n & 0x2 ? -(\$n >> 2 & 0xFFFF) : \$n >> 2 & 0xFFFF # ); # } ## bench( "bitops neg ", sub { # map two integers \$x and \$y into \$n # support negative \$x and \$y for ( 1 .. \$iters ) { \$n = ( abs(\$x) << 18 ) + ( \$x < 0 ? 1 : 0 ) + ( abs(\$y) << 2 ) + ( \$y < 0 ? 2 : 0 ); ( \$xx, \$yy ) = ( \$n & 0x1 ? -(\$n >> 18 ) : \$n >> 18, \$n & 0x2 ? -(\$n >> 2 & 0xFFFF) : \$n >> 2 & 0xFFFF ); } }); bench( "(un)pack ii", sub { for ( 1 .. \$iters ) { \$n = pack 'ii', \$x, \$y; ( \$xx, \$yy ) = unpack 'ii', \$n; } }); bench( "(un)pack i2", sub { for ( 1 .. \$iters ) { \$n = pack 'i2', \$x, \$y; ( \$xx, \$yy ) = unpack 'i2', \$n; } }); exit; sub bench { my ( \$start, \$desc, \$fcn ) = ( scalar time, @_ ); \$fcn->(); printf "duration \$desc %0.03f\n", time - \$start; }