Skip to content

SkyCoords very slow due to FRAME_ATTR_NAMES_SET #5698

@dmopalmer

Description

@dmopalmer

Can we replace FRAME_ATTR_NAMES_SET() with a lazily-reevaluated version? This would cure a lot of speed woes with SkyCoord.

Just creating a SkyCoords object, or accessing an attribute, is very slow (milliseconds or millions of clock cycles) regardless of whether it is one point or a thousand. Profiling shows that the time is almost all spent in FRAME_ATTR_NAMES_SET() sky_coordinate.py:38 :

%timeit x=SkyCoord(5,5,unit=u.deg)
100 loops, best of 3: 3.03 ms per loop
%timeit x=SkyCoord(np.linspace(0,360,1000),np.arange(0,360,1000),unit=u.deg)
100 loops, best of 3: 3.07 ms per loop
x=SkyCoord(5,5,unit=u.deg, frame='fk5')
%timeit x.equinox
1000 loops, best of 3: 846 µs per loop
%prun x=[SkyCoord(5,5,unit=u.deg) for i in range(1000)]
from astropy.coordinates.sky_coordinate import FRAME_ATTR_NAMES_SET
%timeit FRAME_ATTR_NAMES_SET()
1000 loops, best of 3: 875 µs per loop

The profiling shows that FRAME_ATTR_NAMES_SET calls getattr() 252 times each time it is called, which is believable given that the code walks a tree:

def FRAME_ATTR_NAMES_SET():
    """Set of all possible frame-specific attributes"""
    out = set()
    for frame_cls in frame_transform_graph.frame_set:
        for attr in frame_cls.get_frame_attr_names().keys():
            out.add(attr)
    return out

To make astropy less slow, can we do some caching so that it doesn't have to be re-evaluated every single time somebody looks at a SkyCoord attribute or makes a new SkyCoord?

(Do we have to worry about invalidating the cached value? Can we invalidate the cached value if frame_transform_graph.frame_set is changed?).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions