[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]
infinite recursion in bignum->accuracy(123)
-----BEGIN PGP SIGNED MESSAGE-----
Moin,
this is a followup to:
http://groups.google.de/groups?selm=200211270314.gAR3Ed816177%40crypt.compul
ink.co.uk&oe=UTF-8&output=gplain
(please remove linebreak)
Below follows an adventure into bugland, along with explanations, and some
other comments. I also show other bugs in accuracy()/precision() and some
speedups. Anything shown here will appear in v1.65 (soon I hope).
If you have little time, skip to the SUMMARY below, otherwise follow me.
Hugo wrote to me:
>Tels <perl_dummy@bloodgate.com> wrote:
>:Please try the latest debug snapshot of v1.65 at
>:http://bloodgate.com/perl/packages/devel/ and mail me the results. Thanx!
>
>Same recursion problem. Here's the short testcase:
>./perl -Ilib -Mbignum -wle 'bignum->accuracy(5); print bignum->accuracy'
Note: Actually, the print is not neccessary, it hangs at the accuracy()
call.
>This recurses in a loop around <bcmp, objectify, new, round>; after
>some tracking down with diagnostics, the problem seems to be the
>recursive attempt to upgrade in round(): the patch below gets me past
>that, and passes all tests.
Hugo dug around and did good work :)
>Of course you won't see this testing in isolation, since bignum isn't
>part of the same distribution. If you want to test new versions of MBI
>in the core, you may want to grab http://crypt.org/perl/module (and
'modules.txt' in the same place) which I use to automate the process
>of integrating a new version.
But actually I *do* see the bug in isolation, but not on my machine. The
reasons are explained below.
Here is Hugo's patch/fix (I "fixed" a wrapping line):
- --- Math-BigInt-1.65/lib/Math/BigInt.pm Wed Nov 27 18:36:242002
+++ lib/Math/BigInt.pm Thu Nov 28 10:42:54 2002
@@ -893,7 +893,7 @@
$p = ${"$c\::precision"} unless defined $p;
# A == 0 is useless, so undef it to signal no rounding
- - $a = undef if defined $a && $a == 0;
+ $a = undef if !$a;
# no rounding today?
return $self unless defined $a || defined $p; # early out
Interesting to note is that both statements *should* be equivalent, so it
is quite strange to see this fixing the endless loop.
But first more info:
# perl -Mbignum -le 'print bignum->accuracy(42)'
42
# perl -Mbignum=v
bignum v0.13
Math::BigInt::Lite v0.11
Math::BigInt v1.65 lib => Math::BigInt::Calc v0.34
Math::BigFloat v1.40
The reason I don't see the bug is Math::BigInt::Lite. So why does having
installed Math::BigInt::Lite or Hugo's patch fix it?
Some explanations on what happens:
When under use bignum; all constants are converted into Big* objects.
Usually this means BigInt for integers, and BigFloat for floats. However,
if you have Lite installed and the constant fits into a scalar,
Math::BigInt::Lite will be used, on the assumption that it is faster for
small numbers.
So, the culprit is:
bignum->accuracy(5);
Note the '5'. if you write it like this with removed (non-installed) Lite,
you will get something like this:
# perl -Mbignum -wle 'print bignum->accuracy(5)'
Deep recursion on anonymous subroutine at
/usr/local/lib/perl5/5.8.0/Math/BigInt.pm line 896.
Deep recursion on subroutine "Math::BigInt::bcmp" at
/usr/local/lib/perl5/5.8.0/Math/BigInt.pm line 70.
Deep recursion on subroutine "Math::BigInt::objectify" at
/usr/local/lib/perl5/5.8.0/Math/BigInt.pm line 963.
Deep recursion on subroutine "Math::BigInt::new" at
/usr/local/lib/perl5/5.8.0/Math/BigInt.pm line 2510.
Deep recursion on subroutine "Math::BigInt::round" at
/usr/local/lib/perl5/5.8.0/Math/BigInt.pm line 574.
[hangs]
If you try this:
# perl -Mbignum -wle 'print bignum->accuracy("5")'
5
It works! The difference is that in the first case 5 get's converted
via Math::BigInt->new(5) to an object, it the latter case it stays as string
(and is used as numerical scalar value in accuracy()).
And why does giving an object to accuracy() make the code wander into
Recursive-Looping-Land? The reason is the "$a == 0" statement. Since $a
contains an object, overlord er overload kicks in, and calls
"$a->bcmp(0);". Which, unfortunately, uses ref($a)->new(0) to construct
another object from the second arg to compare it (highly inefficient, but
giving the circumstances the best we can do).
The first bcmp() then calls new() with some rounding parameters, and this
leads then to a loop (since new() uses round() which uses accuracy(); which
uses bcmp(), which uses new() etc etc). Or something like this. I think you
get the idea.
So, while Hugo's patch fixes the problem by avoiding to fall into the well,
it would be better if we fill the well and seal it.
A couple of solutions are possible:
* comment round() and avoid using operations that lead to
loops. That's what we didn't want to do. (Note: The same caveat occurs
in accuracy() and probably elsewhere, so just avoiding it is a not good
long term idea)
* fiddle with new() and/or bcmp() and don't let it do rounding. Ugly, and
probably not solvable without making everything slower. Definitely a
no-go.
* Doing away with objects in accuracy(), using scalars instead. This
means scalars go to round(), which will thus not see objects. Hm.
(For bonus points, do the same in round(), just To Be Sure[tm])
The last point sounds strange, because that would introduce a rather hard
limit into our BigInt world, where everything is an arbitrarily big number,
namely A or P beeing a scalar opposed to a BigNumber.
Well, that was a lie. Actually, round() already can only round in the range
of a scalar. This is for performance and practical reasons, like avoiding
infinitely deep recursion and thus even lower performance than you are used
to from BigInt and friends. :) So, the limitation is already build in.
(Also, Calc uses a Perl array to store a number, which also has a build-in
limit)
OTOH, if you try to round a number with more digits than a Perl scalar can
hold, you very probably have exhausted all memory on the system already :o)
(The same for BigFloats, but not counting trailing zeros. So 123e10000
actually has 3 digits as far as the rounding code is concerned, not 10003).
So, we just convert the argument in accuracy() (and precision(), while we
are at it) to a scalar. Interestingly, that not only fixes the bug, it also
makes it faster, and quite a bit!
SUMMARY
=======
The bug described at top is caused by the argument to accuracy() (or
precision) beeing an object. Now these are converted to scalars, which not
only fixes the bug, but also makes it faster.
While I was at this, I also noticed a couple of problems, which I fixed,
too.
* accuracy() and precision() return undef when you set the global A or P,
and then a local A or P and then try to unset the local A or P.
Subsequent calls will return the A (or, you know it already, P) in
effect for the local object, but the call to unset it does not. Testcode:
use Test::More;
use Math::BigInt;
plan tests => 3;
Math::BigInt->accuracy(42);
my $x = Math::BigInt->new(123); # $x gets A of 42, too!
is ($x->accuracy(),42); # really?
is ($x->accuracy(undef),42); # $x has no A, but the
# global is still in effect
# for $x!
is ($x->accuracy(),42); # so $x has still A = 42
The second test will fail with versions up to v1.64. Not a big deal, but
not right, either.
* accuracy() (and it's evil twin, precision()) accept anything you
throw at them, like floats, or garbage:
#!/usr/bin/perl -w
use Test::More;
use Math::BigInt;
plan tests => 1;
isn't ($x->accuracy(4.2), '4.2', ' A must be integer');
isn't ($x->accuracy('abc'), 'abc', 'A must be numeric');
The last test actually dies with:
Argument "abc" isn't numeric in numeric eq (==) at
/usr/local/lib/perl5/5.8.0/Math/BigInt.pm line 229.
accuracy must not be zero at /usr/local/lib/perl5/5.8.0/Math/BigInt.pm
line 229.
Dying is fine, but the famous last words should be correct.
* Speaking of die(), it really should use Carp::croak.
* bignum->accuracy(), bigint->accuracy() and bigrat->accuracy(), as well
as their counter-parts named precision() call the BigInt/BigFloat
routines one time too often just to get the proper return value.
Saves us 1 of 3 (for bignum) respectively 1 of 2 calls in bigint/bigrat
by just inserting a carefully placed "return ".
* The fix from Hugo to round() should also be applied.
Things to do:
* convert A and P arguments to round() to scalars as well?
* when calling bround() or bfround() from accuracy() or precision(), it
seems that bround() and bfround() are a bit inefficient in determing A or
P they have to use. (namely, they try to find it out, instead just using
the value they got just passed)
Anyone wishing to try out the fixed versions, please look for v1.64
(BigInt) and v0.14 (bignum) in:
http://bloodgate.com/perl/packages/devel/
Attached are benchmarks results and the definitions file to generate them.
The benchmark used a v1.64 with Hugo's fix (to avoid endless loop).
Since in v1.39 the Math::BigInt->accuracy() syntax was broken, I used v1.45
as the first version to bench. Results are attached as absolute numbers
(operations/second) and relative to v1.45, 100 meaning as fast as v1.45,
200 twice as fast and so on.
The reason that Math::BigInt->precision(Math::BigInt->new(6)); got slower
(line 2 in precision benchmark) is that it converts the argument to a
scalar, which takes more time over just storing a ref to it. But it makes
using the precision later on much faster, which the benchmark doesn't show.
Also, typically you set the global A or P only once, but use it a lot. Since
accuracy() needs to check the argument for >= 0, setting the global one
actually got a lot faster (line 2 in accuracy benchmark). Using it later on
is also faster.
Also attached are two profiling runs of the following script:
#!/usr/bin/perl -w
use Math::BigInt;
my $x = Math::BigInt->new(123);
my $y = Math::BigInt->new(5);
for (0..10000)
{
$x->accuracy($y);
}
Which show the difference in the calling patterns. v1.64_fixed does
basically 36 calls (!) just for each $x->accuracy($y), while v1.65 needs
only 12 calls. Still too much, but better.
I hope to release v1.65 soon, please send me a lot of questions and
comments. Thanx in advance!
And thank you for listening to one of my boring emails :o)
Best wishes,
Tels
- --
perl -MMath::String -e 'print \
Math::String->from_number("215960156869840440586892398248"),"\n"'
http://bloodgate.com/perl My current Perl projects
PGP key available on http://bloodgate.com/tels.asc or via email.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.
iQEVAwUBPe0TEncLPEOTuEwVAQGOGAf8CZ3cucKoj2U+e6oaiLJ4ah8En2oLdGEl
zi7/n86Tx+UwKycUkGmj0qd8CzlYka/LWNrCVAwQo0+ngsCHbuufzDJQ0PbjvKOb
t0w5XSUK5HKc9GTRv5cD1IeJO4Ze4WKkfYTgX01EypA1K6XWnYOm0FHkr39Hzb62
lZPr4EFGe4MZASi396REaY8M96UWuL7NyTKjzJfzF9iQmZV7SCuwwe5xhlORYro7
XDzYdeAlM3yx1cQiSIiPCp6T0JjHR0lv5l3lQLtGHZpYErt8MNjNSaf+rBBswND2
j00OQtkeEpjusSHWrEqPgsviLBNi0jgdUbKruDXQz0JaZrNLqxCONw==
=1qNO
-----END PGP SIGNATURE-----
Total Elapsed Time = 0.739378 Seconds
User+System Time = 0.719378 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c Name
33.3 0.240 0.950 20002 0.0000 0.0000 Math::BigInt::accuracy
29.1 0.210 0.630 10001 0.0000 0.0001 Math::BigInt::bround
20.8 0.150 0.140 10001 0.0000 0.0000 Math::BigInt::numify
19.4 0.140 0.140 10027 0.0000 0.0000 Math::BigInt::BEGIN
16.6 0.120 0.110 10001 0.0000 0.0000 Math::BigInt::Calc::_len
16.6 0.120 0.210 10001 0.0000 0.0000 Math::BigInt::length
13.9 0.100 0.100 10001 0.0000 0.0000 Math::BigInt::is_zero
5.56 0.040 0.100 1 0.0400 0.0997 main::BEGIN
4.17 0.030 0.020 10001 0.0000 0.0000 Math::BigInt::Calc::_is_zero
2.78 0.020 0.010 10001 0.0000 0.0000 Math::BigInt::_scale_a
2.78 0.020 0.010 10001 0.0000 0.0000 Math::BigInt::Calc::_num
2.78 0.020 0.010 10001 0.0000 0.0000 Math::BigInt::modify
1.39 0.010 0.010 7 0.0014 0.0014 vars::BEGIN
1.39 0.010 0.010 2 0.0050 0.0050 Exporter::as_heavy
0.00 0.000 -0.000 3 0.0000 - Exporter::import
0.00 0.000 -0.000 1 0.0000 - warnings::BEGIN
0.00 0.000 -0.000 3 0.0000 - warnings::register::import
0.00 0.000 -0.000 6 0.0000 - warnings::register::mkMask
0.00 0.000 -0.000 5 0.0000 - strict::import
0.00 0.000 -0.000 20 0.0000 - strict::bits
0.00 0.000 -0.000 1 0.0000 - overload::BEGIN
0.00 0.000 -0.000 1 0.0000 - overload::import
0.00 0.000 -0.000 1 0.0000 - overload::OVERLOAD
0.00 0.000 -0.000 4 0.0000 - constant::BEGIN
0.00 0.000 -0.000 15 0.0000 - strict::unimport
0.00 0.000 -0.000 2 0.0000 - constant::import
0.00 0.000 -0.000 1 0.0000 - Math::BigInt::TIESCALAR
0.00 0.000 -0.000 7 0.0000 - integer::import
0.00 0.000 -0.000 1 0.0000 - Math::BigInt::STORE
0.00 0.000 0.030 1 0.0000 0.0299 Math::BigInt::import
0.00 0.000 0.010 1 0.0000 0.0100 Exporter::export_to_level
0.00 0.000 -0.000 2 0.0000 - Exporter::Heavy::BEGIN
0.00 0.000 -0.000 1 0.0000 - Exporter::Heavy::heavy_export_to_l
0.0000 evel
0.00 0.000 -0.000 1 0.0000 - Exporter::export
0.00 0.000 -0.000 1 0.0000 - Exporter::Heavy::heavy_export
0.00 0.000 -0.000 11 0.0000 - Math::BigInt::Calc::BEGIN
0.00 0.000 -0.000 1 0.0000 - integer::unimport
0.00 0.000 -0.000 1 0.0000 - Math::BigInt::Calc::_base_len
0.00 0.000 -0.000 5 0.0000 - Math::BigInt::Calc::_new
0.00 0.000 -0.000 1 0.0000 - Math::BigInt::Calc::import
Total Elapsed Time = 5.299253 Seconds
User+System Time = 5.259253 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c Name
26.6 1.399 2.810 30004 0.0000 0.0001 Math::BigInt::new
16.3 0.860 3.610 30002 0.0000 0.0001 Math::BigInt::objectify
16.1 0.850 4.800 30002 0.0000 0.0002 Math::BigInt::bcmp
10.6 0.560 0.540 20002 0.0000 0.0000 Math::BigInt::round
10.6 0.560 0.540 20002 0.0000 0.0000 Math::BigInt::_split
8.75 0.460 0.430 30002 0.0000 0.0000 Math::BigInt::Calc::_acmp
8.37 0.440 0.410 30007 0.0000 0.0000 Math::BigInt::Calc::_new
5.89 0.310 3.980 10001 0.0000 0.0004 Math::BigInt::bround
4.18 0.220 4.960 30002 0.0000 0.0002 Math::BigInt::__ANON__
3.04 0.160 0.170 10027 0.0000 0.0000 Math::BigInt::BEGIN
2.66 0.140 0.160 10001 0.0000 0.0000 Math::BigInt::is_zero
2.66 0.140 5.890 20002 0.0000 0.0003 Math::BigInt::accuracy
2.28 0.120 0.110 10001 0.0000 0.0000 Math::BigInt::numify
1.90 0.100 0.150 10001 0.0000 0.0000 Math::BigInt::length
1.52 0.080 0.070 10001 0.0000 0.0000 Math::BigInt::Calc::_len
1.14 0.060 0.050 20013 0.0000 0.0000 Math::BigInt::Calc::BEGIN
1.14 0.060 0.050 10001 0.0000 0.0000 Math::BigInt::_scale_a
0.95 0.050 0.040 10001 0.0000 0.0000 Math::BigInt::Calc::_is_zero
0.76 0.040 0.100 1 0.0400 0.0997 main::BEGIN
0.38 0.020 0.010 10001 0.0000 0.0000 Math::BigInt::Calc::_num
0.38 0.020 0.010 10001 0.0000 0.0000 Math::BigInt::modify
0.19 0.010 0.010 2 0.0050 0.0050 constant::import
0.19 0.010 0.010 7 0.0014 0.0014 vars::BEGIN
0.19 0.010 0.010 2 0.0050 0.0050 Exporter::as_heavy
0.00 0.000 -0.000 3 0.0000 - Exporter::import
0.00 0.000 -0.000 1 0.0000 - warnings::BEGIN
0.00 0.000 -0.000 3 0.0000 - warnings::register::import
0.00 0.000 -0.000 6 0.0000 - warnings::register::mkMask
0.00 0.000 -0.000 5 0.0000 - strict::import
0.00 0.000 -0.000 20 0.0000 - strict::bits
0.00 0.000 -0.000 1 0.0000 - overload::BEGIN
0.00 0.000 -0.000 1 0.0000 - overload::import
0.00 0.000 -0.000 1 0.0000 - overload::OVERLOAD
0.00 0.000 -0.000 4 0.0000 - constant::BEGIN
0.00 0.000 -0.000 15 0.0000 - strict::unimport
0.00 0.000 -0.000 1 0.0000 - Math::BigInt::TIESCALAR
0.00 0.000 -0.000 7 0.0000 - integer::import
0.00 0.000 -0.000 1 0.0000 - Math::BigInt::STORE
0.00 0.000 0.030 1 0.0000 0.0299 Math::BigInt::import
0.00 0.000 0.010 1 0.0000 0.0100 Exporter::export_to_level
BigBench v0.09 (c) Copyright by Tels 2001-2002. Have fun!
Tue Dec 3 21:11:23 2002 Reading templates from 'v1.65-test//'...done.
Got 2 templates.
Tue Dec 3 21:11:23 2002 Reading definitions from def/accuracy.def...done.
Got 20 ops in 2 groups.
Each op will run for at least 2 seconds.
Results are scaled by factor 1 and rounded to 3 digits.
Results will be rounded to integer.
The benchmark will run for approximately 3 minutes.
Running 'v1.64_fixed':
Benchmarking group 1 ('accuracy'):
1 global scalar 5 102000 ops/s
2 global bigint 5 3860 ops/s
3 123 () 156000 ops/s
4 123 undef 110000 ops/s (empty: 36100, both: 27100)
5 123 scalar 5 14200 ops/s (empty: 35900, both: 10200)
6 123 bigint 5 2150 ops/s (empty: 210000, both: 2130)
7 12345 scalar 2 8560 ops/s (empty: 36100, both: 6920)
8 12345 bigint 2 2020 ops/s (empty: 36100, both: 1910)
Average: 49800 ops/s
Benchmarking group 2 ('precision'):
9 global scalar 5 107000 ops/s
10 global bigint 5 103000 ops/s
11 123 () 159000 ops/s
12 123 undef 121000 ops/s (empty: 35700, both: 27600)
13 123 scalar -5 27200 ops/s (empty: 35900, both: 15500)
14 123 bigint -5 5080 ops/s (empty: 35000, both: 4440)
15 12345 scalar -2 27900 ops/s (empty: 35200, both: 15600)
16 12345 bigint -2 5120 ops/s (empty: 35900, both: 4480)
17 123 scalar 5 6190 ops/s (empty: 35600, both: 5270)
18 123 bigint 5 1300 ops/s (empty: 35700, both: 1260)
19 12345 scalar 2 6310 ops/s (empty: 35900, both: 5360)
20 12345 bigint 2 1270 ops/s (empty: 35200, both: 1230)
Average: 47600 ops/s
Running 'v1.65':
Benchmarking group 1 ('accuracy'):
1 global scalar 5 92900 ops/s
2 global bigint 5 34000 ops/s
3 123 () 159000 ops/s
4 123 undef 79000 ops/s (empty: 36400, both: 24900)
5 123 scalar 5 14100 ops/s (empty: 36100, both: 10200)
6 123 bigint 5 8550 ops/s (empty: 215000, both: 8220)
7 12345 scalar 2 8490 ops/s (empty: 36400, both: 6890)
8 12345 bigint 2 7090 ops/s (empty: 36400, both: 5930)
Average: 50300 ops/s
Benchmarking group 2 ('precision'):
9 global scalar 5 105000 ops/s
10 global bigint 5 39100 ops/s
11 123 () 159000 ops/s
12 123 undef 83600 ops/s (empty: 36400, both: 25400)
13 123 scalar -5 27900 ops/s (empty: 36200, both: 15800)
14 123 bigint -5 17800 ops/s (empty: 35500, both: 11900)
15 12345 scalar -2 28100 ops/s (empty: 36200, both: 15800)
16 12345 bigint -2 17300 ops/s (empty: 36400, both: 11700)
17 123 scalar 5 6230 ops/s (empty: 36400, both: 5320)
18 123 bigint 5 5480 ops/s (empty: 36200, both: 4760)
19 12345 scalar 2 6280 ops/s (empty: 36000, both: 5350)
20 12345 bigint 2 5540 ops/s (empty: 36600, both: 4810)
Average: 41800 ops/s
Tue Dec 3 21:15:07 2002 Numbers are relative to v1.64_fixed, 100 denotes 100%.
| v1.65
-----------------+--------
global scalar 5 | 91.0
global bigint 5 | 881
123 () | 102
123 undef | 72.0
123 scalar 5 | 99.0
123 bigint 5 | 398
12345 scalar 2 | 99.0
12345 bigint 2 | 351
accuracy: | 101
.................|........
global scalar 5 | 98.0
global bigint 5 | 38.0
123 () | 100
123 undef | 69.0
123 scalar -5 | 103
123 bigint -5 | 350
12345 scalar -2 | 101
12345 bigint -2 | 338
123 scalar 5 | 101
123 bigint 5 | 422
12345 scalar 2 | 100
12345 bigint 2 | 436
precision: | 87.8
.................|........
Tue Dec 3 21:15:07 2002 All done. Enjoy!
BigBench v0.09 (c) Copyright by Tels 2001-2002. Have fun!
Tue Dec 3 21:07:24 2002 Reading templates from 'v1.65-test//'...done.
Got 2 templates.
Tue Dec 3 21:07:24 2002 Reading definitions from def/accuracy.def...done.
Got 20 ops in 2 groups.
Each op will run for at least 2 seconds.
Results are scaled by factor 1 and rounded to 3 digits.
Results will be rounded to integer.
The benchmark will run for approximately 3 minutes.
Running 'v1.64_fixed':
Benchmarking group 1 ('accuracy'):
1 global scalar 5 104000 ops/s
2 global bigint 5 3900 ops/s
3 123 () 158000 ops/s
4 123 undef 112000 ops/s (empty: 35900, both: 27200)
5 123 scalar 5 14300 ops/s (empty: 35800, both: 10200)
6 123 bigint 5 2130 ops/s (empty: 210000, both: 2110)
7 12345 scalar 2 8660 ops/s (empty: 35200, both: 6950)
8 12345 bigint 2 2030 ops/s (empty: 35500, both: 1920)
Average: 50700 ops/s
Benchmarking group 2 ('precision'):
9 global scalar 5 106000 ops/s
10 global bigint 5 103000 ops/s
11 123 () 159000 ops/s
12 123 undef 115000 ops/s (empty: 36100, both: 27400)
13 123 scalar -5 27600 ops/s (empty: 35700, both: 15600)
14 123 bigint -5 5070 ops/s (empty: 35700, both: 4440)
15 12345 scalar -2 27300 ops/s (empty: 36000, both: 15500)
16 12345 bigint -2 5110 ops/s (empty: 35300, both: 4460)
17 123 scalar 5 6220 ops/s (empty: 35300, both: 5290)
18 123 bigint 5 1310 ops/s (empty: 35700, both: 1260)
19 12345 scalar 2 6320 ops/s (empty: 35800, both: 5370)
20 12345 bigint 2 1250 ops/s (empty: 35400, both: 1210)
Average: 46900 ops/s
Running 'v1.65':
Benchmarking group 1 ('accuracy'):
1 global scalar 5 92000 ops/s
2 global bigint 5 34200 ops/s
3 123 () 160000 ops/s
4 123 undef 82800 ops/s (empty: 36300, both: 25200)
5 123 scalar 5 14000 ops/s (empty: 36500, both: 10100)
6 123 bigint 5 8590 ops/s (empty: 213000, both: 8260)
7 12345 scalar 2 8440 ops/s (empty: 36100, both: 6840)
8 12345 bigint 2 7050 ops/s (empty: 36300, both: 5900)
Average: 50900 ops/s
Benchmarking group 2 ('precision'):
9 global scalar 5 105000 ops/s
10 global bigint 5 39100 ops/s
11 123 () 161000 ops/s
12 123 undef 89300 ops/s (empty: 36400, both: 25800)
13 123 scalar -5 28000 ops/s (empty: 36400, both: 15800)
14 123 bigint -5 17200 ops/s (empty: 36500, both: 11700)
15 12345 scalar -2 28000 ops/s (empty: 36400, both: 15800)
16 12345 bigint -2 17500 ops/s (empty: 36200, both: 11800)
17 123 scalar 5 6170 ops/s (empty: 36400, both: 5270)
18 123 bigint 5 5420 ops/s (empty: 36500, both: 4720)
19 12345 scalar 2 6380 ops/s (empty: 36200, both: 5420)
20 12345 bigint 2 5520 ops/s (empty: 36100, both: 4790)
Average: 42300 ops/s
Tue Dec 3 21:11:08 2002 Numbers are absolute ops/s, scaled by factor 1.
| v1.64 v1.65
| fixed
-----------------+-----------------
global scalar 5 | 104000 92000
global bigint 5 | 3900 34200
123 () | 158000 160000
123 undef | 112000 82800
123 scalar 5 | 14300 14000
123 bigint 5 | 2130 8590
12345 scalar 2 | 8660 8440
12345 bigint 2 | 2030 7050
accuracy: | 50700 50900
.................|.................
global scalar 5 | 106000 105000
global bigint 5 | 103000 39100
123 () | 159000 161000
123 undef | 115000 89300
123 scalar -5 | 27600 28000
123 bigint -5 | 5070 17200
12345 scalar -2 | 27300 28000
12345 bigint -2 | 5110 17500
123 scalar 5 | 6220 6170
123 bigint 5 | 1310 5420
12345 scalar 2 | 6320 6380
12345 bigint 2 | 1250 5520
precision: | 46900 42300
.................|.................
Tue Dec 3 21:11:09 2002 All done. Enjoy!
###############################################################################
# BigBenchmark data file.
#
# Contains all the groups and ops you want to benchmark.
#
# Format is as follows:
#
# For defining groups:
# group=groupid#groupname#groupdescription
# The ops follow the group defintion and go like this:
# opid#opname#startupcode#emptycode#benchmarkcode
#
# The opid is to sort the ops in one group, they will be done numerically
# sorted. Same goes for group id's, lowest id will be benchmarked first.
# You can leave group and op id's empty (set to 0), then they will be
# filled-in automatically.
#
# The startup code is done before running the benchmark, so set any variables
# you need there. The empty code is benchmarked and then subtracted from the
# benchmark's code timing.
###############################################################################
# BigInt/BigFloat:
# You should use $c->new(); instead of Math::BigInt->new() etc, so that
# the benchmarks are independed of the actual class used.
# Actual definitions:
group=accuracy#0#BigInt accuracy()
0#global scalar 5###$c->accuracy(5);
0#global bigint 5#$x=$c->new(5);##$c->accuracy($x);
0#123 ()#$c->accuracy(undef);$x=$c->new('123');##$x->accuracy();
0#123 undef#$x=$c->new('123');#$x->copy();#$x->copy()->accuracy(undef);
0#123 scalar 5#$x=$c->new('123');#$x->copy();#$x->copy()->accuracy(5);
0#123 bigint 5#$x=$c->new('123');$y=$c->new(5)#$c->copy();#$x->copy()->accuracy(
$y);
0#12345 scalar 2#$x=$c->new('12345');#$x->copy();#$x->copy()->accuracy(2);
0#12345 bigint 2#$x=$c->new('12345');$y=$c->new(2)#$x->copy();#$x->copy()->accur
acy($y);
group=precision#0#BigInt precision()
0#global scalar 5###$c->precision(5);
0#global bigint 5#$x=$c->new(5);##$c->precision($x);
0#123 ()#$x=$c->new('123');##$x->precision();
0#123 undef#$c->precision(undef);$x=$c->new('123');#$x->copy();#$x->copy()->prec
ision(undef);
0#123 scalar -5#$x=$c->new('123');#$x->copy();#$x->copy()->precision(-5);
0#123 bigint -5#$x=$c->new('123');$y=$c->new(-5)#$x->copy()#$x->copy()->precisio
n($y);
0#12345 scalar -2#$x=$c->new('12345');#$x->copy();#$x->copy()->precision(-2);
0#12345 bigint -2#$x=$c->new('12345');$y=$c->new(-2)#$x->copy();#$x->copy()->pre
cision($y);
0#123 scalar 5#$x=$c->new('123');#$x->copy();#$x->copy()->precision(5);
0#123 bigint 5#$x=$c->new('123');$y=$c->new(5)#$x->copy();#$x->copy()->precision
($y);
0#12345 scalar 2#$x=$c->new('12345');#$x->copy();#$x->copy()->precision(2);
0#12345 bigint 2#$x=$c->new('12345');$y=$c->new(2)#$x->copy();#$x->copy()->preci
sion($y);
[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]