pack-test.pl


#!/usr/bin/perl

use v5.010;
use strict;
use warnings;
use Benchmark qw(:all);

my $len                 = 20_000;
my $size                = 100;
my $frozen_haystack     = pack( 'Ca*', $size, pack( "(Z$size)*", 1 .. $len ) );
my $frozen_haystack_ref = \$frozen_haystack;

my $unpacked_size = unpack( 'C', ${$frozen_haystack_ref} );
my $format = 'Z' . 100;

my $mid        = $len / 2;
my $ptr        = unpack( 'L!', pack( 'P', $frozen_haystack ) );
my $ptr_format = 'P' . $size;

sub format_xZ {
    my $element =
      unpack( 'x' . ( $size * $mid + 1 ) . $format, ${$frozen_haystack_ref} );
    return $element;
}

sub format_P {
    my $element = unpack( $ptr_format, pack( 'L!', $ptr + $size * $mid + 1 ) );
    return $element;
}

print "xZ: ", format_xZ(), "\n";
print " P: ", format_P(),  "\n";

cmpthese(
    1_000_000,
    {
        'xZ format' => \&format_xZ,
        'P format'  => \&format_P,
    } );

cmpthese(
    1_000_000,
    {
        concat => sub { return 'x' . ( $size * $mid + 1 ) . $format },
        unpack => sub { return pack( 'L!', $ptr + $size * $mid + 1 ) },
    } );

my $static_format = 'x' . ( $size * $mid + 1 ) . $format;
my $static_ptr = pack( 'L!', $ptr + $size * $mid + 1 );
cmpthese(
    1_000_000,
    {
        'static xZ format' => sub {
            my $element = unpack( $static_format, ${$frozen_haystack_ref} );
            return $element;
        },
        'static P format' => sub {
            my $element = unpack( $ptr_format, $static_ptr );
            return $element;
          }
    } );