use strict; use warnings; use Benchmark qw(cmpthese); my @data28 = map {int (rand () * 256)} 1..28; printf "%02x ", $_ for @data28; print "\n"; my @xlate = thereAndBack (@data28); printf "%02x ", $_ for @xlate; print "\n\n"; my @data280 = map {int (rand () * 256)} 1..280; my @data2800 = map {int (rand () * 256)} 1..2800; cmpthese (-1, { data28 => sub {thereAndBack (@data28)}, data280 => sub {thereAndBack (@data280)}, data2800 => sub {thereAndBack (@data2800)}, } ); sub thereAndBack { return fromKarma (toKarma (@_)); } sub toKarma { die "Blocks must be multiples of 8 bytes" if @_ % 7; my @raw = @_; my @karma; while (@raw) { my @block = splice @raw, 0, 7; my $extra = 0; for my $byte (@block) { $extra |= $byte & 0x80; $byte &= 0x7F; $extra >>= 1; } push @karma, ($extra, @block); } return @karma; } sub fromKarma { die "Blocks must be multiples of 8 bytes" if @_ % 8; my @karma = @_; my @raw; while (@karma) { my @block = splice @karma, 0, 8; my $extra = shift @block; for my $byte (reverse @block) { $extra <<= 1; $byte |= $extra & 0x80; } push @raw, @block; } return @raw; } #### 37 8b a0 23 ef 46 68 f8 a1 75 71 de aa eb 0e ee 08 54 c7 77 9f 0b ee d7 d3 f4 34 69 37 8b a0 23 ef 46 68 f8 a1 75 71 de aa eb 0e ee 08 54 c7 77 9f 0b ee d7 d3 f4 34 69 Rate data2800 data280 data28 data2800 124/s -- -90% -98% data280 1228/s 888% -- -85% data28 8200/s 6496% 568% --