in reply to Re: Converting an array of bytes into a BigInt - 1500% quicker.
in thread Converting an array of bytes into a BigInt - speed considerations
It would be interesting to put the other offered solutions into the benchmark, but sleep calls.
BTW, you get a more accurate average if you use a negative timing. Benchmark.pm will run the benchmark until the clock ticks over, whereas unless your count is really high you stand a good chance of being on the misleading side of the tick.
Cheers,
#!/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 <<EVAL or die $@; print '$comp',"\n",$comp,"\n"; 1 EVAL } cmpthese(-10, $comphash); __END__
ba2bi2(@bytes) +123456781234567812345678123456781234567812345678123456781234567812345 +67812345678 bytearray_to_bigint2(@bytes) +123456781234567812345678123456781234567812345678123456781234567812345 +67812345678 ba2bi2_nomap(@bytes) +123456781234567812345678123456781234567812345678123456781234567812345 +67812345678 ba2bi2_unpack(@bytes) +123456781234567812345678123456781234567812345678123456781234567812345 +67812345678 bytearray_to_bigint(@bytes) +123456781234567812345678123456781234567812345678123456781234567812345 +67812345678 ba2bi2_clean(@bytes) +123456781234567812345678123456781234567812345678123456781234567812345 +67812345678 Benchmark: running ba2bi2, clean, mult, nomap, shift, unpack, each for at least 10 CPU s +econds... ba2bi2: 13 wallclock secs (10.76 usr + 0.01 sys = 10.77 CPU) @ 69 +.21/s (n=745) clean: 12 wallclock secs (10.29 usr + 0.00 sys = 10.29 CPU) @ 68 +.55/s (n=705) mult: 12 wallclock secs (10.12 usr + 0.00 sys = 10.12 CPU) @ 5 +.24/s (n=53) nomap: 12 wallclock secs (10.08 usr + 0.00 sys = 10.08 CPU) @ 69 +.48/s (n=700) shift: 12 wallclock secs (10.28 usr + 0.02 sys = 10.30 CPU) @ 6 +.99/s (n=72) unpack: 12 wallclock secs (10.13 usr + 0.00 sys = 10.13 CPU) @ 71 +.05/s (n=720) Rate mult shift clean ba2bi2 nomap unpack mult 5.24/s -- -25% -92% -92% -92% -93% shift 6.99/s 33% -- -90% -90% -90% -90% clean 68.5/s 1208% 881% -- -1% -1% -4% ba2bi2 69.2/s 1221% 890% 1% -- -0% -3% nomap 69.5/s 1226% 894% 1% 0% -- -2% unpack 71.0/s 1256% 917% 4% 3% 2% --
--- demerphq
my friends call me, usually because I'm late....
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Re: Re: Converting an array of bytes into a BigInt - 1500% quicker.
by BrowserUk (Patriarch) on Jan 24, 2003 at 05:36 UTC | |
by demerphq (Chancellor) on Jan 24, 2003 at 18:14 UTC |