Skip to content

Commit

Permalink
Blanks as singleton (#1081)
Browse files Browse the repository at this point in the history
Looking at the initialization process, `Blank*` PatternObjets are
created several times. This PR makes that these elements be created just
once when a parameter is not provided. This would also help to optimize
the pattern-matching algorithm when we face that problem.
  • Loading branch information
mmatera authored Aug 31, 2024
1 parent 1c04aee commit 1bebd2c
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 13 deletions.
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ Internals
Operator precedence has been gone over and is picked up in tables from the Mathics Scanner project.


Performance
-----------

* `Blank*` patterns without arguments are now singletons.


7.0.0
-----

Expand Down
16 changes: 16 additions & 0 deletions mathics/builtin/patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,22 @@ def get_default_value(
class _Blank(PatternObject):
arg_counts = [0, 1]

_instance = None

def __new__(cls, *args, **kwargs):
if kwargs.get("expression", None) is False:
return super().__new__(cls, *args, **kwargs)

num_elem = len(args[0].elements)
assert num_elem < 2, f"{cls} should have at most an element."

if num_elem != 0:
return super().__new__(cls, *args, **kwargs)
# no arguments. Use the singleton
if cls._instance is None:
cls._instance = super().__new__(cls, *args, **kwargs)
return cls._instance

def init(
self, expr: Expression, evaluation: OptionalType[Evaluation] = None
) -> None:
Expand Down
25 changes: 12 additions & 13 deletions mathics/core/builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
from mathics.core.list import ListExpression
from mathics.core.number import PrecisionValueError, dps, get_precision, min_prec
from mathics.core.parser.util import PyMathicsDefinitions, SystemDefinitions
from mathics.core.rules import BuiltinRule, Pattern, Rule
from mathics.core.pattern import Pattern
from mathics.core.rules import BuiltinRule, Rule
from mathics.core.symbols import (
BaseElement,
BooleanType,
Expand Down Expand Up @@ -191,16 +192,15 @@ def __new__(cls, *args, **kwargs):
# well documented.
# Notice that this behavior was used extensively in
# mathics.builtin.inout

if kwargs.get("expression", None) is not False:
return to_expression(cls.get_name(), *args)
else:
instance = super().__new__(cls)
if not instance.formats:
# Reset formats so that not every instance shares the same
# empty dict {}
instance.formats = {}
return instance

instance = super().__new__(cls)
if not instance.formats:
# Reset formats so that not every instance shares the same
# empty dict {}
instance.formats = {}
return instance

def __init__(self, *args, **kwargs):
super().__init__()
Expand Down Expand Up @@ -472,12 +472,11 @@ def is_literal(self) -> bool:
class BuiltinElement(Builtin, BaseElement):
def __new__(cls, *args, **kwargs):
new_kwargs = kwargs.copy()
# In a Builtin element, we never return an Expression object,
# so we create it with the option `expression=False`.
new_kwargs["expression"] = False
instance = super().__new__(cls, *args, **new_kwargs)
if not instance.formats:
# Reset formats so that not every instance shares the same empty
# dict {}
instance.formats = {}
# If `expression` is not `False`, we need to initialize the object:
if kwargs.get("expression", None) is not False:
try:
instance.init(*args, **kwargs)
Expand Down

0 comments on commit 1bebd2c

Please sign in to comment.