Skip to content

Commit c41b366

Browse files
committed
PERF: faster dir() calls
1 parent efb068f commit c41b366

File tree

7 files changed

+31
-16
lines changed

7 files changed

+31
-16
lines changed

doc/source/whatsnew/v1.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ Performance improvements
346346
- Performance improvement in :meth:`RollingGroupby.count` (:issue:`35625`)
347347
- Small performance decrease to :meth:`Rolling.min` and :meth:`Rolling.max` for fixed windows (:issue:`36567`)
348348
- Reduced peak memory usage in :meth:`DataFrame.to_pickle` when using ``protocol=5`` in python 3.8+ (:issue:`34244`)
349+
- faster `dir` calls when many index labels, e.g. `dir(ser)` (:issue:`xxxxx`)
349350
- Performance improvement in :class:`ExpandingGroupby` (:issue:`37064`)
350351

351352
.. ---------------------------------------------------------------------------

pandas/core/accessor.py

+1-8
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,7 @@ def _dir_additions(self) -> Set[str]:
2424
"""
2525
Add additional __dir__ for this object.
2626
"""
27-
rv = set()
28-
for accessor in self._accessors:
29-
try:
30-
getattr(self, accessor)
31-
rv.add(accessor)
32-
except AttributeError:
33-
pass
34-
return rv
27+
return {accessor for accessor in self._accessors if hasattr(self, accessor)}
3528

3629
def __dir__(self) -> List[str]:
3730
"""

pandas/core/generic.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -5439,11 +5439,7 @@ def _dir_additions(self) -> Set[str]:
54395439
add the string-like attributes from the info_axis.
54405440
If info_axis is a MultiIndex, it's first level values are used.
54415441
"""
5442-
additions = {
5443-
c
5444-
for c in self._info_axis.unique(level=0)[:100]
5445-
if isinstance(c, str) and c.isidentifier()
5446-
}
5442+
additions = self._info_axis._dir_additions_for_owner
54475443
return super()._dir_additions().union(additions)
54485444

54495445
# ----------------------------------------------------------------------

pandas/core/indexes/base.py

+13
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
NewType,
1313
Optional,
1414
Sequence,
15+
Set,
1516
Tuple,
1617
TypeVar,
1718
Union,
@@ -568,6 +569,18 @@ def _engine(self):
568569
target_values = self._get_engine_target()
569570
return self._engine_type(lambda: target_values, len(self))
570571

572+
@cache_readonly
573+
def _dir_additions_for_owner(self) -> Set[str_t]:
574+
"""
575+
Add the string-like attributes from this index to the owners' dir output.
576+
If this is a MultiIndex, it's first level values are used.
577+
"""
578+
return {
579+
c
580+
for c in self.unique(level=0)[:100]
581+
if isinstance(c, str) and c.isidentifier()
582+
}
583+
571584
# --------------------------------------------------------------------
572585
# Array-Like Methods
573586

pandas/core/indexes/datetimelike.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Base and utility classes for tseries type pandas objects.
33
"""
44
from datetime import datetime, tzinfo
5-
from typing import TYPE_CHECKING, Any, List, Optional, TypeVar, Union, cast
5+
from typing import TYPE_CHECKING, Any, List, Optional, Set, TypeVar, Union, cast
66

77
import numpy as np
88

@@ -105,6 +105,10 @@ class DatetimeIndexOpsMixin(ExtensionIndex):
105105
def _is_all_dates(self) -> bool:
106106
return True
107107

108+
@cache_readonly
109+
def _dir_additions_for_owner(self) -> Set[str]:
110+
return set()
111+
108112
# ------------------------------------------------------------------------
109113
# Abstract data attributes
110114

pandas/core/indexes/interval.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from functools import wraps
33
from operator import le, lt
44
import textwrap
5-
from typing import TYPE_CHECKING, Any, List, Optional, Tuple, Union, cast
5+
from typing import TYPE_CHECKING, Any, List, Optional, Set, Tuple, Union, cast
66

77
import numpy as np
88

@@ -371,6 +371,10 @@ def __contains__(self, key: Any) -> bool:
371371
def _multiindex(self) -> MultiIndex:
372372
return MultiIndex.from_arrays([self.left, self.right], names=["left", "right"])
373373

374+
@cache_readonly
375+
def _dir_additions_for_owner(self) -> Set[str]:
376+
return set()
377+
374378
@cache_readonly
375379
def values(self) -> IntervalArray:
376380
"""

pandas/core/indexes/numeric.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any
1+
from typing import Any, Set
22

33
import numpy as np
44

@@ -184,6 +184,10 @@ def _union(self, other, sort):
184184
else:
185185
return super()._union(other, sort)
186186

187+
@cache_readonly
188+
def _dir_additions_for_owner(self) -> Set[str]:
189+
return set()
190+
187191

188192
_num_index_shared_docs[
189193
"class_descr"

0 commit comments

Comments
 (0)