#!/usr/bin/perl -w use strict; use warnings; use Math::BigInt; use Benchmark 'cmpthese'; our $bigint; our @bytes; sub bigint_to_bytearray { my $bigint = shift; my @bytes; while(1) { my ($q,$r) = $bigint->brsft(8); push(@bytes,$r+0); last if $q == 0; $bigint = Math::BigInt->new($q); } return @bytes; } ## This is the one I would like to speed up ## The array looks something like (127,6,64,27,166,33 .... ) sub bytearray_to_bigint { my @array = @_; my $count = Math::BigInt->new('0'); my $result = Math::BigInt->new('0'); foreach my $a (@array) { $result += $a * (256**$count++); } return $result; } sub bytearray_to_bigint2 { my $result = Math::BigInt->new('0'); for my $byte (reverse @_) { my $tmp = Math::BigInt->new($byte); $result = $result->blsft(8); $result += $tmp; } return $result; } sub ba2bi2 { my @ba = reverse (@_, (0) x (4 - ( @_%4 || 4 ) ) ); my $result = Math::BigInt->new(0); $result *= 4294967296 , $result += $_ for map{ unpack 'N' , pack 'C4' , @ba[4*$_ .. 4*$_+3] } 0 .. ($#ba/4); return $result; } sub ba2bi2_clean { my @ba = reverse (@_, (0) x (4 - ( @_%4 || 4 ) ) ); my $result = Math::BigInt->new(0); for (0 .. ($#ba/4)) { $result *= 4294967296; $result += unpack 'N', pack 'C4', @ba[4*$_ .. 4*$_+3] } return $result; } sub ba2bi2_nomap { my @ba = reverse (@_, (0) x (4 - ( @_%4 || 4 ) ) ); my $result = Math::BigInt->new(0); $result *= 4294967296, $result += unpack 'N', pack 'C4', @ba[4*$_ .. 4*$_+3] for (0 .. ($#ba/4)); return $result; } sub ba2bi2_unpack { my $result = Math::BigInt->new(0); $result *= 4294967296, $result += $_ for unpack 'N*', reverse pack 'C'.(4*int(@_/4+1)), @_; return $result; } $|++; $bigint = Math::BigInt->new('12345678' x 10); @bytes = bigint_to_bytearray($bigint); my $comphash={ 'mult' => 'bytearray_to_bigint(@bytes)', 'shift' => 'bytearray_to_bigint2(@bytes)', 'ba2bi2' => 'ba2bi2(@bytes)', 'nomap' => 'ba2bi2_nomap(@bytes)', 'clean' => 'ba2bi2_clean(@bytes)', 'unpack' => 'ba2bi2_unpack(@bytes)', }; foreach my $comp (values %$comphash) { eval <