You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I was doing some profiling on isel, and see there are some properties that (I think) never change, but are called frequently. Should we cache these on their object?
Here's a case: we call LazilyOuterIndexedArray.shape frequently when doing a simple indexing operation. Each call takes ~150µs. An attribute lookup on a python object takes ~50ns (i.e. 3000x faster). IIUC the result on that property should never change.
I don't think this is the solution to performance issues, and there's some additional complexity.
Could they be easy & small wins, though?
By reading the implementation of cachedproperty, it needs a __dict__. It should be straightforward to write a variant that uses slots though.
Is there a way of doing that which doesn't nullify the benefits of slots? i.e. if we add a _cache_dict to the class, is that the same overhead as having a __dict__?
I prefer pandas.utils.cache_readonly to the Python 3.8 cachedproperty. Besides not needing a dict, it is also written in cython, which should make a substantial difference.
max-sixty could you post your benchmark where you measure 150us? I tried caching that property with @cache_readonly and I only get a boost of 7us.
Activity
shoyer commentedon Nov 12, 2019
I think this would be totally fine to add. A variant on
cache_readonlyappears in Python 3.8 standard library asfunctools.cached_property. I think we could backport that pretty easily:https://github.com/python/cpython/blob/d360346640e19231032b072216195484fa2450b4/Lib/functools.py#L924
max-sixty commentedon Nov 12, 2019
Great, I didn't know about that, thanks
It does remind me, though, that I'm not sure it's possible given we're using
__slots__, at least without adding an entry to__slots__...https://github.com/python/cpython/blob/d360346640e19231032b072216195484fa2450b4/Lib/functools.py#L954-L958
crusaderky commentedon Nov 12, 2019
By reading the implementation of cachedproperty, it needs a
__dict__. It should be straightforward to write a variant that uses slots though.max-sixty commentedon Nov 13, 2019
Is there a way of doing that which doesn't nullify the benefits of slots? i.e. if we add a
_cache_dictto the class, is that the same overhead as having a__dict__?crusaderky commentedon Nov 14, 2019
@max-sixty afraid so. But as I said it should be straightforward to use a variant that instead of
self.__dict__[self.name]uses getattr/setattr.crusaderky commentedon Nov 14, 2019
I prefer
pandas.utils.cache_readonlyto the Python 3.8cachedproperty. Besides not needing a dict, it is also written in cython, which should make a substantial difference.max-sixty could you post your benchmark where you measure 150us? I tried caching that property with @cache_readonly and I only get a boost of 7us.
With
@property: 187usWith
@cache_readonly: 180uscrusaderky commentedon Nov 14, 2019
Output (uncached):