Skip to content

Commit 9ed4b58

Browse files
committed
implemented faster metadata handling
.meta can be None and Metadata() is only created when needed
1 parent a4d6b33 commit 9ed4b58

File tree

2 files changed

+39
-26
lines changed

2 files changed

+39
-26
lines changed

doc/source/changes/version_0_30.rst.inc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,11 @@ Miscellaneous improvements
295295
* allowed to pass a single axis or group as ``axes_to_reindex`` argument
296296
of the :py:obj:`LArray.reindex()` method (closes :issue:`712`).
297297

298+
* substantially improved performance of creating, iterating, and doing a few other operations over larray objects.
299+
This solves a few pathological cases of slow operations, especially those involving many small-ish arrays but sadly
300+
the overall performance improvement is negligible over most of the real-world models using larray that we tested these
301+
changes on.
302+
298303

299304
Fixes
300305
^^^^^

larray/core/array.py

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -558,14 +558,22 @@ def nan_equal(a1, a2):
558558
return a1.eq(a2, nans_equal=True)
559559

560560

561-
def _handle_deprecated_argument_title(meta, title):
562-
if meta is None:
563-
meta = Metadata()
561+
def _handle_meta(meta, title):
562+
"""
563+
Make sure meta is either None or a Metadata instance
564+
"""
564565
if title is not None:
565-
import warnings
566-
warnings.warn("title argument is deprecated. Please use meta argument instead", FutureWarning, stacklevel=3)
566+
if meta is None:
567+
meta = Metadata()
568+
warnings.warn("title argument is deprecated. Please use meta argument instead", FutureWarning, stacklevel=2)
567569
meta['title'] = title
568-
return meta
570+
if meta is None or isinstance(meta, Metadata):
571+
return meta
572+
# XXX: move this test in Metadata.__init__?
573+
if not isinstance(meta, (list, dict, OrderedDict)):
574+
raise TypeError("Expected None, list of pairs, dict, OrderedDict or Metadata object "
575+
"instead of {}".format(type(meta).__name__))
576+
return Metadata(meta)
569577

570578

571579
class LArray(ABCLArray):
@@ -685,14 +693,14 @@ def __init__(self, data, axes=None, title=None, meta=None, dtype=None):
685693
self.data = data
686694
self.axes = axes
687695

688-
meta = _handle_deprecated_argument_title(meta, title)
689-
self.meta = meta
696+
meta = _handle_meta(meta, title)
697+
self._meta = meta
690698

691699
@property
692700
def title(self):
693701
import warnings
694702
warnings.warn("title attribute is deprecated. Please use meta.title instead", FutureWarning, stacklevel=2)
695-
return self._meta.title if 'title' in self._meta else None
703+
return self._meta.title if self._meta is not None and 'title' in self._meta else None
696704

697705
@title.setter
698706
def title(self, title):
@@ -711,14 +719,13 @@ def meta(self):
711719
Metadata:
712720
Metadata of the array.
713721
"""
722+
if self._meta is None:
723+
self._meta = Metadata()
714724
return self._meta
715725

716726
@meta.setter
717727
def meta(self, meta):
718-
if not isinstance(meta, (list, dict, OrderedDict, Metadata)):
719-
raise TypeError("Expected list of pairs or dict or OrderedDict or Metadata object "
720-
"instead of {}".format(type(meta).__name__))
721-
self._meta = meta if isinstance(meta, Metadata) else Metadata(meta)
728+
self._meta = _handle_meta(meta, None)
722729

723730
# TODO: rename to inonzero and implement a label version of nonzero
724731
# TODO: implement wildcard argument to avoid producing the combined labels
@@ -7400,7 +7407,8 @@ def zeros(axes, title=None, dtype=float, order='C', meta=None):
74007407
BE 0.0 0.0
74017408
FO 0.0 0.0
74027409
"""
7403-
meta = _handle_deprecated_argument_title(meta, title)
7410+
# FIXME: the error message is wrong (stackdepth is wrong) because of _check_axes_argument
7411+
meta = _handle_meta(meta, title)
74047412
axes = AxisCollection(axes)
74057413
return LArray(np.zeros(axes.shape, dtype, order), axes, meta=meta)
74067414

@@ -7436,7 +7444,7 @@ def zeros_like(array, title=None, dtype=None, order='K', meta=None):
74367444
a0 0 0 0
74377445
a1 0 0 0
74387446
"""
7439-
meta = _handle_deprecated_argument_title(meta, title)
7447+
meta = _handle_meta(meta, title)
74407448
return LArray(np.zeros_like(array, dtype, order), array.axes, meta=meta)
74417449

74427450

@@ -7472,7 +7480,7 @@ def ones(axes, title=None, dtype=float, order='C', meta=None):
74727480
BE 1.0 1.0
74737481
FO 1.0 1.0
74747482
"""
7475-
meta = _handle_deprecated_argument_title(meta, title)
7483+
meta = _handle_meta(meta, title)
74767484
axes = AxisCollection(axes)
74777485
return LArray(np.ones(axes.shape, dtype, order), axes, meta=meta)
74787486

@@ -7508,7 +7516,7 @@ def ones_like(array, title=None, dtype=None, order='K', meta=None):
75087516
a0 1 1 1
75097517
a1 1 1 1
75107518
"""
7511-
meta = _handle_deprecated_argument_title(meta, title)
7519+
meta = _handle_meta(meta, title)
75127520
axes = array.axes
75137521
return LArray(np.ones_like(array, dtype, order), axes, meta=meta)
75147522

@@ -7545,7 +7553,7 @@ def empty(axes, title=None, dtype=float, order='C', meta=None):
75457553
BE 2.47311483356e-315 2.47498446195e-315
75467554
FO 0.0 6.07684618082e-31
75477555
"""
7548-
meta = _handle_deprecated_argument_title(meta, title)
7556+
meta = _handle_meta(meta, title)
75497557
axes = AxisCollection(axes)
75507558
return LArray(np.empty(axes.shape, dtype, order), axes, meta=meta)
75517559

@@ -7582,7 +7590,7 @@ def empty_like(array, title=None, dtype=None, order='K', meta=None):
75827590
a1 1.06099789568e-313 1.48539705397e-313
75837591
a2 1.90979621226e-313 2.33419537056e-313
75847592
"""
7585-
meta = _handle_deprecated_argument_title(meta, title)
7593+
meta = _handle_meta(meta, title)
75867594
# cannot use empty() because order == 'K' is not understood
75877595
return LArray(np.empty_like(array.data, dtype, order), array.axes, meta=meta)
75887596

@@ -7629,7 +7637,7 @@ def full(axes, fill_value, title=None, dtype=None, order='C', meta=None):
76297637
BE 0 1
76307638
FO 0 1
76317639
"""
7632-
meta = _handle_deprecated_argument_title(meta, title)
7640+
meta = _handle_meta(meta, title)
76337641
if isinstance(fill_value, Axis):
76347642
raise ValueError("If you want to pass several axes or dimension lengths to full, you must pass them as a "
76357643
"list (using []) or tuple (using()).")
@@ -7673,7 +7681,7 @@ def full_like(array, fill_value, title=None, dtype=None, order='K', meta=None):
76737681
a0 5 5 5
76747682
a1 5 5 5
76757683
"""
7676-
meta = _handle_deprecated_argument_title(meta, title)
7684+
meta = _handle_meta(meta, title)
76777685
# cannot use full() because order == 'K' is not understood
76787686
# cannot use np.full_like() because it would not handle LArray fill_value
76797687
res = empty_like(array, dtype=dtype, meta=meta)
@@ -7787,7 +7795,7 @@ def sequence(axis, initial=0, inc=None, mult=1, func=None, axes=None, title=None
77877795
year 2016 2017 2018 2019
77887796
1.0 2.0 3.0 3.0
77897797
"""
7790-
meta = _handle_deprecated_argument_title(meta, title)
7798+
meta = _handle_meta(meta, title)
77917799

77927800
if inc is None:
77937801
inc = 1 if mult is 1 else 0
@@ -7984,7 +7992,7 @@ def ndtest(shape_or_axes, start=0, label_start=0, title=None, dtype=int, meta=No
79847992
BE 0 1
79857993
FO 2 3
79867994
"""
7987-
meta = _handle_deprecated_argument_title(meta, title)
7995+
meta = _handle_meta(meta, title)
79887996
# XXX: try to come up with a syntax where start is before "end".
79897997
# For ndim > 1, I cannot think of anything nice.
79907998
if isinstance(shape_or_axes, int):
@@ -8135,7 +8143,7 @@ def labels_array(axes, title=None, meta=None):
81358143
# nat\\sex M F
81368144
# BE BE,M BE,F
81378145
# FO FO,M FO,F
8138-
meta = _handle_deprecated_argument_title(meta, title)
8146+
meta = _handle_meta(meta, title)
81398147
axes = AxisCollection(axes)
81408148
if len(axes) > 1:
81418149
res_axes = axes + Axis(axes.names, 'axis')
@@ -8205,7 +8213,7 @@ def eye(rows, columns=None, k=0, title=None, dtype=None, meta=None):
82058213
1 0.0 0.0 1.0
82068214
2 0.0 0.0 0.0
82078215
"""
8208-
meta = _handle_deprecated_argument_title(meta, title)
8216+
meta = _handle_meta(meta, title)
82098217
if columns is None:
82108218
columns = rows.copy() if isinstance(rows, Axis) else rows
82118219
axes = AxisCollection([rows, columns])
@@ -8404,7 +8412,7 @@ def stack(elements=None, axis=None, title=None, meta=None, dtype=None, **kwargs)
84048412
M 0.0 0.5
84058413
F 0.0 0.5
84068414
"""
8407-
meta = _handle_deprecated_argument_title(meta, title)
8415+
meta = _handle_meta(meta, title)
84088416

84098417
from larray import Session
84108418

0 commit comments

Comments
 (0)