Skip to content

Commit 32cfd6f

Browse files
author
Release Manager
committed
Trac #32775: Mostly fix slow down by #30022
We avoid multiple imports caused by #30022: Before (and with #30022): {{{ sage: a = 1/1000 sage: %timeit a.__pari__() 810 ns ± 2.33 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) sage: p = a.__pari__() sage: %timeit QQ(p) 1.52 µs ± 1.37 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) sage: a = 12314 sage: %timeit a.__pari__() 723 ns ± 0.804 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) sage: p = a.__pari__() sage: %timeit ZZ(p) 715 ns ± 1.32 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) sage: %timeit a.divisors(method='pari') 1.23 µs ± 1.51 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) sage: %timeit a.is_prime_power() 647 ns ± 0.164 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) sage: %timeit a.is_prime() 604 ns ± 0.486 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) sage: %timeit a.factor() 3.6 µs ± 13.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) }}} Reverting #30022: {{{ sage: a = 1/1000 sage: %timeit a.__pari__() 221 ns ± 0.289 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) sage: p = a.__pari__() sage: %timeit QQ(p) 810 ns ± 0.852 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) sage: a = 12314 sage: %timeit a.__pari__() 176 ns ± 0.217 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) sage: p = a.__pari__() sage: %timeit ZZ(p) 150 ns ± 0.104 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) sage: %timeit a.divisors(method='pari') 643 ns ± 1.38 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) sage: %timeit a.is_prime_power() 53.9 ns ± 0.336 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) sage: %timeit a.is_prime() 58 ns ± 0.174 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) sage: %timeit a.factor() 2.99 µs ± 4.62 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) }}} With this ticket: {{{ sage: a = 1/1000 sage: %timeit a.__pari__() 274 ns ± 0.344 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) sage: p = a.__pari__() sage: %timeit QQ(p) 867 ns ± 0.999 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) sage: a = 12314 sage: %timeit a.__pari__() 200 ns ± 0.0656 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) sage: p = a.__pari__() sage: %timeit ZZ(p) 183 ns ± 0.179 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) sage: %timeit a.divisors(method='pari') 673 ns ± 0.928 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) sage: %timeit a.is_prime_power() 88.4 ns ± 0.075 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) sage: %timeit a.is_prime() 68.9 ns ± 0.0878 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) sage: %timeit a.factor() 3.19 µs ± 10.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) }}} URL: https://trac.sagemath.org/32775 Reported by: gh-kliem Ticket author(s): Jonathan Kliem Reviewer(s): Matthias Koeppe, Samuel Lelièvre
2 parents 1277457 + 4d7ac2f commit 32cfd6f

File tree

2 files changed

+57
-26
lines changed

2 files changed

+57
-26
lines changed

src/sage/rings/integer.pyx

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,15 @@ except ImportError:
198198
pari_gen = ()
199199

200200

201+
set_integer_from_gen = None
202+
pari_divisors_small = None
203+
n_factor_to_list = None
204+
pari_is_prime_power = None
205+
pari_is_prime = None
206+
objtogen = None
207+
new_gen_from_integer = None
208+
209+
201210
cdef extern from *:
202211
int unlikely(int) nogil # Defined by Cython
203212

@@ -637,7 +646,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
637646
raise TypeError("Cannot convert non-integral float to integer")
638647

639648
elif isinstance(x, pari_gen):
640-
from sage.libs.pari.convert_sage import set_integer_from_gen
649+
global set_integer_from_gen
650+
if set_integer_from_gen is None:
651+
from sage.libs.pari.convert_sage import set_integer_from_gen
641652
set_integer_from_gen(self, x)
642653

643654
else:
@@ -3046,12 +3057,14 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
30463057
raise ValueError("n must be nonzero")
30473058

30483059
if (method is None or method == 'pari') and mpz_fits_slong_p(self.value):
3049-
try:
3050-
from sage.libs.pari.convert_sage import pari_divisors_small
3051-
except ImportError:
3052-
if method == 'pari':
3053-
raise ImportError("method `pari` requested, but cypari2 not present")
3054-
else:
3060+
global pari_divisors_small
3061+
if pari_divisors_small is None:
3062+
try:
3063+
from sage.libs.pari.convert_sage import pari_divisors_small
3064+
except ImportError:
3065+
if method == 'pari':
3066+
raise ImportError("method `pari` requested, but cypari2 not present")
3067+
if pari_divisors_small is not None:
30553068
if mpz_sgn(self.value) > 0:
30563069
return pari_divisors_small(self)
30573070
else:
@@ -3909,11 +3922,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
39093922
return factor_trial_division(self, limit)
39103923

39113924
if mpz_fits_slong_p(n.value):
3912-
try:
3913-
from sage.libs.flint.ulong_extras import n_factor_to_list
3914-
except ImportError:
3915-
pass
3916-
else:
3925+
global n_factor_to_list
3926+
if n_factor_to_list is None:
3927+
try:
3928+
from sage.libs.flint.ulong_extras import n_factor_to_list
3929+
except ImportError:
3930+
pass
3931+
if n_factor_to_list is not None:
39173932
if proof is None:
39183933
from sage.structure.proof.proof import get_flag
39193934
proof = get_flag(proof, "arithmetic")
@@ -5108,11 +5123,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
51085123
return (self, zero) if get_data else False
51095124

51105125
if mpz_fits_slong_p(self.value):
5111-
try:
5112-
from sage.libs.pari.convert_sage import pari_is_prime_power
5113-
except ImportError:
5114-
pass
5115-
else:
5126+
global pari_is_prime_power
5127+
if pari_is_prime_power is None:
5128+
try:
5129+
from sage.libs.pari.convert_sage import pari_is_prime_power
5130+
except ImportError:
5131+
pass
5132+
if pari_is_prime_power is not None:
51165133
return pari_is_prime_power(self, get_data)
51175134

51185135
cdef long n
@@ -5194,11 +5211,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
51945211
return False
51955212

51965213
if mpz_fits_ulong_p(self.value):
5197-
try:
5198-
from sage.libs.pari.convert_sage import pari_is_prime
5199-
except ImportError:
5200-
pass
5201-
else:
5214+
global pari_is_prime
5215+
if pari_is_prime is None:
5216+
try:
5217+
from sage.libs.pari.convert_sage import pari_is_prime
5218+
except ImportError:
5219+
pass
5220+
if pari_is_prime is not None:
52025221
return pari_is_prime(self)
52035222

52045223
if proof is None:
@@ -5550,7 +5569,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
55505569
55515570
55525571
"""
5553-
from cypari2.gen import objtogen
5572+
global objtogen
5573+
if objtogen is None:
5574+
from cypari2.gen import objtogen
55545575
if self.is_square():
55555576
raise ValueError("class_number not defined for square integers")
55565577
if not self%4 in [0,1]:
@@ -5958,7 +5979,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
59585979
1041334
59595980
59605981
"""
5961-
from sage.libs.pari.convert_sage import new_gen_from_integer
5982+
global new_gen_from_integer
5983+
if new_gen_from_integer is None:
5984+
from sage.libs.pari.convert_sage import new_gen_from_integer
59625985
return new_gen_from_integer(self)
59635986

59645987
def _interface_init_(self, I=None):

src/sage/rings/rational.pyx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ except ImportError:
110110
pari_gen = ()
111111

112112

113+
set_rational_from_gen = None
114+
new_gen_from_rational = None
115+
116+
113117
cdef sage.rings.fast_arith.arith_int ai
114118
ai = sage.rings.fast_arith.arith_int()
115119

@@ -650,7 +654,9 @@ cdef class Rational(sage.structure.element.FieldElement):
650654
mpq_canonicalize(self.value)
651655

652656
elif isinstance(x, pari_gen):
653-
from sage.libs.pari.convert_sage import set_rational_from_gen
657+
global set_rational_from_gen
658+
if set_rational_from_gen is None:
659+
from sage.libs.pari.convert_sage import set_rational_from_gen
654660
set_rational_from_gen(self, x)
655661

656662
elif isinstance(x, list) and len(x) == 1:
@@ -3777,7 +3783,9 @@ cdef class Rational(sage.structure.element.FieldElement):
37773783
sage: m.type()
37783784
't_FRAC'
37793785
"""
3780-
from sage.libs.pari.convert_sage import new_gen_from_rational
3786+
global new_gen_from_rational
3787+
if new_gen_from_rational is None:
3788+
from sage.libs.pari.convert_sage import new_gen_from_rational
37813789
return new_gen_from_rational(self)
37823790

37833791
def _interface_init_(self, I=None):

0 commit comments

Comments
 (0)