Skip to content

Commit b2a379b

Browse files
committed
perf(polys): don't create Basic instance for Poly
When creating a Poly instance the underlying rep object should be stored as an instances and the corresponding Basic/Expr instance should only be created on demand. This commit reverts a prevoius change [0] that instantiated the corresponding Expr for every Poly resulting in a slowdown for Poly-intensive code such as the Risch algorithm [1]. [0] sympy#18513 [1] sympy#19199
1 parent f6fe028 commit b2a379b

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

sympy/polys/polytools.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class Poly(Basic):
132132
133133
"""
134134

135-
__slots__ = ('rep',)
135+
__slots__ = ('rep', 'gens')
136136

137137
is_commutative = True
138138
is_Poly = True
@@ -158,6 +158,15 @@ def __new__(cls, rep, *gens, **args):
158158
else:
159159
return cls._from_expr(rep, opt)
160160

161+
# Poly does not pass its args to Basic.__new__ to be stored in _args so we
162+
# have to emulate them here with an args property that derives from rep
163+
# and gens which are instance attributes. This also means we need to
164+
# define _hashable_content. The _hashable_content is rep and gens but args
165+
# uses expr instead of rep (expr is the Basic version of rep). Passing
166+
# expr in args means that Basic methods like subs should work. Using rep
167+
# otherwise means that Poly can remain more efficient than Basic by
168+
# avoiding creating a Basic instance just to be hashable.
169+
161170
@classmethod
162171
def new(cls, rep, *gens):
163172
"""Construct :class:`Poly` instance from raw representation. """
@@ -167,20 +176,22 @@ def new(cls, rep, *gens):
167176
elif rep.lev != len(gens) - 1:
168177
raise PolynomialError("invalid arguments: %s, %s" % (rep, gens))
169178

170-
expr = basic_from_dict(rep.to_sympy_dict(), *gens)
171-
172-
obj = Basic.__new__(cls, expr, *gens)
179+
obj = Basic.__new__(cls)
173180
obj.rep = rep
181+
obj.gens = gens
174182

175183
return obj
176184

177185
@property
178186
def expr(self):
179-
return self.args[0]
187+
return basic_from_dict(self.rep.to_sympy_dict(), *self.gens)
180188

181189
@property
182-
def gens(self):
183-
return self.args[1:]
190+
def args(self):
191+
return (self.expr,) + self.gens
192+
193+
def _hashable_content(self):
194+
return (self.rep,) + self.gens
184195

185196
@classmethod
186197
def from_dict(cls, rep, *gens, **args):

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy