From f61845f39c9f932ed84d84f2505b96edf3e4624b Mon Sep 17 00:00:00 2001 From: Tels Date: Fri, 10 Dec 2004 12:13:48 -0800 Subject: [PATCH] import Math-BigInt-GMP 1.16 from CPAN git-cpan-module: Math-BigInt-GMP git-cpan-version: 1.16 git-cpan-authorid: TELS git-cpan-file: authors/id/T/TE/TELS/math/Math-BigInt-GMP-1.16.tar.gz --- BUGS | 1 - CHANGES | 4 +++ GMP.xs | 80 +++++++++++++++++++++++------------------- MANIFEST | 3 ++ META.yml | 19 +++++----- Makefile.PL | 30 ++++++++++++++-- NEW | 30 ++++++---------- SIGNATURE | 33 +++++++++-------- build/README | 3 ++ build/leak.pl | 41 ++++++++++++++++++++++ build/leaktest | 4 +++ lib/Math/BigInt/GMP.pm | 23 +++--------- 12 files changed, 167 insertions(+), 104 deletions(-) create mode 100644 build/README create mode 100644 build/leak.pl create mode 100755 build/leaktest diff --git a/BUGS b/BUGS index 852495c..136bb39 100644 --- a/BUGS +++ b/BUGS @@ -2,7 +2,6 @@ Known bugs: * Some problems with left/right shifting in base != 2 seem to occur -* There might be some memory leaks - check the XS code! Please send me test-reports, your experiences with this and your ideas - I love to hear about my work! diff --git a/CHANGES b/CHANGES index 8490641..3baf397 100644 --- a/CHANGES +++ b/CHANGES @@ -136,6 +136,10 @@ * do not pull unused parameter "Class" from stack - avoid compiler warnings * put _sub() into XS for more speed and smaller memory footprint * testsuite from MBI v1.73 +2004-12-09 v1.16 Tels 5112 tests + * fixed a leak in _div() (Thanx Tassilo v. Parsival!) + * put _div() into XS, making division slightly faster for small numbers + * put leak.pl and leaktest into MANIFEST for later checking Please send me test-reports, your experiences with this and your ideas - I love to hear about my work! diff --git a/GMP.xs b/GMP.xs index 680639a..2f96c52 100644 --- a/GMP.xs +++ b/GMP.xs @@ -150,7 +150,7 @@ _num(Class, n) RETVAL ############################################################################## -# _zeros() - return string +# _zeros() - return number of trailing zeros (in decimal form) int _zeros(Class,n) @@ -370,8 +370,8 @@ _sub(Class,x,y, ...) mpz_sub(*TEMP_2, *TEMP, *TEMP_1); - /* PUSHs(sv_setref_pv(sv_newmortal(), "Math::BigInt::GMP", (void*)TEMP_2)); */ - PUSHs(sv_setref_pv(y, "Math::BigInt::GMP", (void*)TEMP_2)); + PUSHs(sv_setref_pv(sv_newmortal(), "Math::BigInt::GMP", (void*)TEMP_2)); + /*PUSHs(sv_setref_pv(y, "Math::BigInt::GMP", (void*)TEMP_2)); */ } else { @@ -450,44 +450,50 @@ _mul(Class,x,y) PUSHs( x ); ############################################################################## -# _div_two() - -mpz_t * -div_two(m,n) - mpz_t * m - mpz_t * n - - CODE: - NEW_GMP_MPZ_T_INIT; - mpz_div(*RETVAL, *m, *n); - OUTPUT: - RETVAL - - -############################################################################## -# _bdiv_two() +# _div(): x /= y or (x,rem) = x / y +# was in perl: +#sub _div +# { +# i f (wantarray) +# { +# # return (a/b,a%b) +# my $r; +# ($_[1],$r) = Math::BigInt::GMP::bdiv_two($_[1],$_[2]); +# return ($_[1], $r); +# } +# # return a / b +# Math::BigInt::GMP::div_two($_[1],$_[2]); +# } void -bdiv_two(m,n) - mpz_t * m - mpz_t * n - +_div(Class,x,y) + SV* x + SV* y PREINIT: - mpz_t * quo; + mpz_t* TEMP; + mpz_t* TEMP_1; mpz_t * rem; PPCODE: - quo = malloc (sizeof(mpz_t)); - rem = malloc (sizeof(mpz_t)); - mpz_init(*quo); - mpz_init(*rem); - mpz_tdiv_qr(*quo, *rem, *m, *n); - EXTEND(SP, 2); - PUSHs(sv_setref_pv(sv_newmortal(), "Math::BigInt::GMP", (void*)quo)); - PUSHs(sv_setref_pv(sv_newmortal(), "Math::BigInt::GMP", (void*)rem)); - + GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */ + if (GIMME_V == G_ARRAY) + { + /* former bdiv_two() routine */ + rem = malloc (sizeof(mpz_t)); + mpz_init(*rem); + mpz_tdiv_qr(*TEMP, *rem, *TEMP, *TEMP_1); + EXTEND(SP, 2); + PUSHs( x ); + PUSHs(sv_setref_pv(sv_newmortal(), "Math::BigInt::GMP", (void*)rem)); + } + else + { + /* former div_two() routine */ + mpz_div(*TEMP, *TEMP, *TEMP_1); /* x /= y */ + PUSHs( x ); + } ############################################################################## -# _mod() : x %= y +# _mod() - x %= y void _mod(Class,x,y) @@ -569,7 +575,7 @@ _is_ten(Class,x) RETVAL ############################################################################## -# _pow() - m **= n +# _pow() - x **= y void _pow(Class,x,y) @@ -674,7 +680,7 @@ _copy(Class,m) ############################################################################## -# _is_odd() - test for number beeing odd +# _is_odd() - test for number being odd int _is_odd(Class,n) @@ -686,7 +692,7 @@ _is_odd(Class,n) RETVAL ############################################################################## -# _is_even() - test for number beeing even +# _is_even() - test for number being even int _is_even(Class,n) diff --git a/MANIFEST b/MANIFEST index f128212..3e363e0 100644 --- a/MANIFEST +++ b/MANIFEST @@ -9,6 +9,9 @@ NEW SIGNATURE TODO GMP.xs +build/README +build/leak.pl +build/leaktest typemap Makefile.PL lib/Math/BigInt/GMP.pm diff --git a/META.yml b/META.yml index da414e9..3b6394b 100644 --- a/META.yml +++ b/META.yml @@ -1,12 +1,11 @@ -# http://module-build.sourceforge.net/META-spec.html -#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# -name: Math-BigInt-GMP -version: 1.15 +--- #YAML:1.0 +name: Math-BigInt-GMP +version: 1.16 version_from: lib/Math/BigInt/GMP.pm -installdirs: site -requires: - Math::BigFloat: 1.47 - Math::BigInt: 1.73 - +license: perl distribution_type: module -generated_by: ExtUtils::MakeMaker version 6.17 +generated_by: Math-BigInt-GMP version 1.16 +installdirs: site +requires: + Math::BigFloat: 1.47 + Math::BigInt: 1.73 diff --git a/Makefile.PL b/Makefile.PL index 4f9b7f6..0b0f51d 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,6 +1,32 @@ use ExtUtils::MakeMaker; -# See lib/ExtUtils/MakeMaker.pm for details of how to influence -# the contents of the Makefile that is written. + +sub MY::metafile { + package MY; + my $self = shift; + if (!eval { require YAML; 1 }) + { + warn ("YAML not installed, cannot override metafile"); return $self->SUPER::metafile_target(@_); + }; + + my $node = new YAML::Node {}; + + $node->{name} = $self->{DISTNAME}; + $node->{version} = $self->{VERSION}; + $node->{version_from} = $self->{VERSION_FROM}; + $node->{license} = 'perl'; + $node->{distribution_type} = 'module'; + $node->{generated_by} = "$self->{DISTNAME} version $self->{VERSION}"; + $node->{installdirs} = 'site'; + $node->{requires} = $self->{PREREQ_PM}; + + my $dump = YAML::Dump( $node ); + + $dump =~ s/^(.*)$/\t\$(NOECHO) \$(ECHO) "$1" >>META.yml/gm; + $dump =~ s/>>META\.yml/>META.yml/; + + return "metafile:\n$dump"; +} + WriteMakefile( 'NAME' => 'Math::BigInt::GMP', 'VERSION_FROM' => 'lib/Math/BigInt/GMP.pm', # finds $VERSION diff --git a/NEW b/NEW index b277e49..052da82 100644 --- a/NEW +++ b/NEW @@ -1,28 +1,18 @@ Changes between the last and this version: -v1.15: - * some small cleanups in the Perl code - * changed "class" to "Class" to avoid the reserved keyword for MS compiler - * do not pull unused parameter "Class" from stack - avoid warnings when - compiling - that makes the .so a tad smaller and should make it ever so - slightly faster, too - * put _sub() into XS for more speed and smaller memory footprint - * testsuite from MBI v1.73 +v1.16: + * fixed a leak in _div() and simplified it (Thanx Tassilo v. Parseval) + * moved the _div() code to XS to make it a bit faster + * put leak.pl and leaktest into MANIFEST for later checking ############################################################################# -Benchmarking Math::BigInt sub (e.g. what an actual user would see): - -Math::BigInt v1.73, Math::BigInt::GMP v1.14: - - 221 - 444: 5s (5.23 usr + 0.02 sys = 5.25 CPU) @ 15603/s (n=81919) - 444 - 221: 6s (5.21 usr + 0.02 sys = 5.23 CPU) @ 16968/s (n=88744) - -Math::BigInt v1.73, Math::BigInt::GMP v1.15: +v1.15: + 221 / 444: 5 wallclock secs ( 5.20 usr + 0.01 sys = 5.21 CPU) @ 18940/s (n=98679) + 444 / 221: 6 wallclock secs ( 5.20 usr + 0.01 sys = 5.21 CPU) @ 19108/s (n=99555) -Benchmark: running 221 - 444, 444 - 221 for at least 5 CPU seconds... - 221 - 444: 5s (5.25 usr + 0.02 sys = 5.27 CPU) @ 18031/s (n=95024) +15% - 444 - 221: 5s (5.15 usr + 0.01 sys = 5.16 CPU) @ 18080/s (n=93297) + 6% +v1.16: + 221 / 444: 6 wallclock secs ( 5.24 usr + 0.01 sys = 5.25 CPU) @ 20957/s (n=110026) + 444 / 221: 5 wallclock secs ( 5.28 usr + 0.00 sys = 5.28 CPU) @ 21231/s (n=112102) -############################################################################# diff --git a/SIGNATURE b/SIGNATURE index 2fd1e26..52a2237 100644 --- a/SIGNATURE +++ b/SIGNATURE @@ -13,19 +13,22 @@ not run its Makefile.PL or Build.PL. -----BEGIN PGP SIGNED MESSAGE----- -SHA1 51d611e269430c79a8db4a7bc398194137590a77 BUGS -SHA1 9bb0ec36c0fc2bf1663c8ae96467675351b1d313 CHANGES +SHA1 70d6187d0152848c922dc4360fa6dd3a3dc35c62 BUGS +SHA1 3743ce85e7e98c882bd05ec9eebcfb31ff453815 CHANGES SHA1 dda5ca4f413031e9efcaa1600461d5e2adaa3a40 CREDITS -SHA1 217c2605f67abaedc94b165a49fbfa354098320f GMP.xs +SHA1 636480140c61a18f193b0178dc9809c295d9456a GMP.xs SHA1 1c219a49ee07891ca39de3f89ce4bbe02549af82 INSTALL SHA1 d6a6c30ee6d9ba6b9afab8bbf6a25e1b23c744e0 LICENSE -SHA1 402312551dc318b81e4b019598f0a554a30ad19e MANIFEST -SHA1 ca636deea1d19c35aab021e40df02d512d6fb706 META.yml -SHA1 1a382f5cedc17253c2302bea4775553e051eb0ed Makefile.PL -SHA1 2a975cdc9772832517a4a17a645f3a5f0fa26864 NEW +SHA1 6cd50151e6eab24927bce91ec062e6d71724ce63 MANIFEST +SHA1 9c0c8cf77b1ce503893fba602c9ea48cb1d996b9 META.yml +SHA1 185af48c59491c5e3351c6d9950c3565de74005a Makefile.PL +SHA1 704f02fad759cc0d99558352f5a7cfb7d8c11b1e NEW SHA1 e9de29b6e5e9a5e446231b5b12b644f6ed2caafc README SHA1 e4fd0b099ed6ef332c72cbf85719a7cf1bd2dc6a TODO -SHA1 97cfde06ff8c19aa21584f4a26c94a350e2ffd3b lib/Math/BigInt/GMP.pm +SHA1 fd48d0d8750eb949e485d8136b5b424fe73e9775 build/README +SHA1 c93694211f8ba09c49ae69b5f3fd4d957bd26f62 build/leak.pl +SHA1 ac25bda8a6eb9058a9e42a8943c3e11b9fed88dc build/leaktest +SHA1 bed207cfb72446fcb746c8d438538b6801a181fd lib/Math/BigInt/GMP.pm SHA1 7704eb924e8a297edafa95c5075df502bbc2f14a t/bigfltpm.inc SHA1 3287807111be40445e3f8ed5cb1f738996e2b18d t/bigfltpm.t SHA1 b0f41f0025528cfea909c9a212c2e377ee3d9243 t/bigintg.t @@ -35,11 +38,11 @@ SHA1 f7aad87c0a30330d474f4fb45f6d1953d6701d2f typemap -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) -iQEVAwUBQXlxM3cLPEOTuEwVAQHIyAf8CNz6LiY/ki8KgUJAkOE6HJtvW3Xu29LK -nzwxNztXocGMSCrW7uTUqGnPdDLPDW7tsonWabdzav8eRnuBRRroTfjSHNfSJnvt -hOOxWsiKaedQgjQS5xoarTlQbemxzIeibPDbx0zAFFAD7/KjfQbyfsKNIkHl+cCP -3FZL/GIQ4LQfPf9iEDA4BUsZUOuUOHUeUIkwBma9dGVH7C3ph6Y7ydTXKT2d7Y2I -JF5Ij1/VjI3xq+wMsT8adJTwfRTlgw3DUOoOVzPVgb/mrKYyQf0WvE32xvRe4kAR -PI6aHHjFnzpTlfrOptquYCXgWsRGzbN2m63zkCJNYwzHPnlBZson8g== -=SY15 +iQEVAwUBQboC9XcLPEOTuEwVAQFPLQf+Olfms17l/g4dhwcRpRLtaAm525xWEtiV +ARQnCf/xIYfhmDR4deih71aDX6PXjRjihukU+OtPIMdE6MyHUUbzvNqGa0waPIor +O+eOqZlZnyjJLvFGKZXJJtFF39M0ZSzmrMh9wuYvRzQhdKNXgqCju20Ni9puw6IA +tD+V7Y0I5FkXJOCewy8NECoXnQjlcSAiWHZRsByDkJSLA6pBtoQUXuzN73D8I1P/ +JEOuQTQ0ZlF+kFs9wSShOoYYc16OS/EGcBWHw8F8jdzENErmUZ/RP7E9E4fMewey +0MnJ9V2gRHu5Qe8oaoQs8UcaqrWOE5QG/bhW7rcXCVRL4RxNXv0iTw== +=GgRM -----END PGP SIGNATURE----- diff --git a/build/README b/build/README new file mode 100644 index 0000000..beab0e9 --- /dev/null +++ b/build/README @@ -0,0 +1,3 @@ +This directory contains scripts that are used by the developers. + +They are not necessarily usefull for users :) diff --git a/build/leak.pl b/build/leak.pl new file mode 100644 index 0000000..275e44d --- /dev/null +++ b/build/leak.pl @@ -0,0 +1,41 @@ +#!/usr/bin/perl -w + +use strict; +use lib 'lib'; +use lib 'blib/arch'; +use Math::BigInt lib => 'GMP'; +use Devel::Leak; + +my $x = Math::BigInt->new(44); +my $y = Math::BigInt->new(21); + +require Scalar::Util; # otherwise the first sub would do this + +my $xg = Math::BigInt::GMP->_new("44"); +my $yg = Math::BigInt::GMP->_new("21"); + +for my $do ( + [ sub { $xg = Math::BigInt::GMP->_div($xg,$yg); 1; }, 'divide direct' ], + [ sub { my $z = $x / $y; 1; }, 'divide' ], + [ sub { my $z = $x - $y; 1; }, 'subtract' ], + [ sub { my $z = $x + $y; 1; }, 'add' ], + [ sub { my $z = $x % $y; 1; }, 'mod' ], + [ sub { my $z = $x ** $y; 1; }, 'pow' ], + [ sub { my $z = $x ^ $y; 1; }, 'xor' ], + [ sub { my $z = $x | $y; 1; }, 'ior' ], + [ sub { my $z = $x & $y; 1; }, 'and' ], + [ sub { my $z = $x; $z -= $y; 1; }, '-=' ], + [ sub { my $z = $x; $z += $y; 1; }, '+=' ], + [ sub { my $z = $x; $z %= $y; 1; }, '%=' ], + [ sub { my $z = $x; $z /= $y; 1; }, '/=' ], + [ sub { my ($q,$r) = $x->copy()->bdiv($y); 1; }, '(q,r) = x / y' ], + ) + { + my $handle; + my $count = Devel::Leak::NoteSV($handle); + for (1..10) { &{$do->[0]}; } + print "$do->[1] leaked ", Devel::Leak::CheckSV($handle) - $count, " things\n"; + } + +exit; + diff --git a/build/leaktest b/build/leaktest new file mode 100755 index 0000000..262cb8e --- /dev/null +++ b/build/leaktest @@ -0,0 +1,4 @@ +#!/bin/sh + +valgrind --leak-check=yes perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t + diff --git a/lib/Math/BigInt/GMP.pm b/lib/Math/BigInt/GMP.pm index c1c4933..af67c6a 100644 --- a/lib/Math/BigInt/GMP.pm +++ b/lib/Math/BigInt/GMP.pm @@ -12,12 +12,11 @@ require DynaLoader; use vars qw/@ISA $VERSION/; @ISA = qw(Exporter DynaLoader); -$VERSION = '1.15'; +$VERSION = '1.16'; bootstrap Math::BigInt::GMP $VERSION; -sub import { } # catch and throw away - +sub import { } # catch and throw away sub api_version() { 1; } # we are compatible with MBI v1.70 and up BEGIN @@ -26,21 +25,7 @@ BEGIN *_str = \&_num; } -############################################################################## -# actual math code (this could also be put into GMP.xs for more speed) - -sub _div - { - if (wantarray) - { - # return (a/b,a%b) - my $r; - ($_[1],$r) = Math::BigInt::GMP::bdiv_two($_[1],$_[2]); - return ($_[1], $r); - } - # return a / b - $_[1] = Math::BigInt::GMP::div_two($_[1],$_[2]); - } +# Routines not present here are in GMP.xs ############################################################################## # testing @@ -119,7 +104,7 @@ sub _log_int $exact = 0 if $a != 0; } - return ($x,$exact); + ($x,$exact); } 1;