in reply to Re: Re: Converting an array of bytes into a BigInt - 1500% quicker.
in thread Converting an array of bytes into a BigInt - speed considerations
That's interesting. I did have a go at coming up with my own 'clean' version after posting. That's generally the way it works with me. I get something to work, post then try and clean it up and optimise it without breaking it. The biggest headache was working out where and how much padding to add. The rest came relatively easily, if convoluted. I guess I'm a messy thinker.
Anyway, my best effort at a cleaner version is this, which is somewhat different again. TIMWTDI indeed.
I had thought that be getting rid of the reverse, this would be be a benefit. It is on smaller numbers:sub ba2bi3 { my $ba = pack 'C*', (@_, (0) x (4 - ( @_ % 4 || 4 ) ) ); my $result = Math::BigInt->new(0); my $p = length($ba) - 4; do { $result <<= 32; #!4294967296; $result += unpack 'V', substr $ba, $p , 4; } while ($p-=4) >= 0; $result; } print ba2bi3( bigint_to_bytearray( Math::BigInt->new('1234567890' x 8) + ) );
11: +1234567890 <<Length and value under test Benchmark: running best, clean, new, org , each for at least 10 CPU seconds best: 11 wallclock secs (10.59 usr + 0.00 sys = 10.59 CPU) @ 20 +8.58/s (n=2208) clean: 11 wallclock secs (10.55 usr + 0.00 sys = 10.55 CPU) @ 21 +3.94/s (n=2256) new: 11 wallclock secs (10.51 usr + 0.00 sys = 10.51 CPU) @ 60 +.26/s (n=633) org: 11 wallclock secs (10.35 usr + 0.00 sys = 10.35 CPU) @ 24 +.36/s (n=252) Rate org new best clean org 24.4/s -- -60% -88% -89% new 60.3/s 147% -- -71% -72% best 209/s 756% 246% -- -3% clean 214/s 778% 255% 3% -- The results are the same
However, when the numbers get larger, the benefit disappears, swamped by the gains of 4-bytes-at -a-time processing and the cost of BigInt math as here.
301: +1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 1234567890123456789012345678901234567890 12345678901234567890 Benchmark: running best, clean, new, org , each for at least 10 CPU seconds ... s/iter org new clean best org 5.82 -- -77% -94% -94% new 1.31 344% -- -73% -73% clean 0.352 1555% 273% -- -1% best 0.349 1569% 276% 1% -- The results are the same
I'm intrigued by the differences in the benchmarks on your machine and mine. Even when I run mine on an 80-byte number as you did, I still get gains of well over 1000%. I can only assume that your machine is using a compiled big int library, rather than the pure perl versionI am stuck with. Still, iif the performance difference is only a factor of 2, perl's doing pretty damn well I think.
For comaprison I stuck your quickest version into my benchmark and ran it with the 300 digit number of my original benchmark and got these results.
C:\test>229290 Name "main::ba" used only once: possible typo at C:\test\229290.pl lin +e 67. 301: +12345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890 12345678901234567890123456789012345678901234567890 Benchmark: running best, clean, demerphq, new, org , each for at least + 10 CPU seconds Rate org new clean demerphq best org 0.173/s -- -78% -94% -94% -94% new 0.770/s 345% -- -73% -73% -73% clean 2.83/s 1533% 267% -- -1% -1% demerphq 2.86/s 1553% 272% 1% -- -0% best 2.86/s 1553% 272% 1% 0% -- The results are the same
Well done for cracking the no-intermediate-string version (ba2bi2_unpack), I was certain that was possible, but didn't succeed in getting there.
BTW. I realise I had snipped it off on my original post, but as you can see from the above, I do generally use the clock-tick seconds, rather than the iteration's method of benchmarking these days. Mostly because it gives me a reasonable indication of how long the run is likely to take. I always do nice long run (make myself a cup of coffee and drink it long) before I come to a conclusion.
Now just think of the numbers you could get on a 64 bit machine :^)
Examine what is said, not who speaks.
The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Re: Re: Re: Converting an array of bytes into a BigInt - 1500% quicker.
by demerphq (Chancellor) on Jan 24, 2003 at 18:14 UTC |